Add changes for Windows Sotre that went missing with my clumsy Git skills

pull/174/head
Jeffrey Walton 2016-05-03 00:23:05 -04:00
parent 69f7802b53
commit d294b4290b
21 changed files with 428 additions and 123 deletions

View File

@ -33,9 +33,26 @@
// #define NO_OS_DEPENDENCE // #define NO_OS_DEPENDENCE
// Define this to use features provided by Microsoft's CryptoAPI. // Define this to use features provided by Microsoft's CryptoAPI.
// Currently the only feature used is random number generation. // Currently the only feature used is Windows random number generation.
// This macro will be ignored if NO_OS_DEPENDENCE is defined. // This macro will be ignored if NO_OS_DEPENDENCE is defined.
// #define USE_MS_CRYPTOAPI
// Define this to use features provided by Microsoft's CryptoNG API.
// CryptoNG API is available in Vista and above and its cross platform,
// including desktop apps and store apps. Currently the only feature
// used is Windows random number generation.
// This macro will be ignored if NO_OS_DEPENDENCE is defined.
// #define USE_MS_CNGAPI
// If the user did not make a choice, then select CryptoNG if either
// Visual Studio 2015 is available, or Windows 10 or above is available.
#if !defined(USE_MS_CRYPTOAPI) && !defined(USE_MS_CNGAPI)
# if (_MSC_VER >= 1900) || ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/))
# define USE_MS_CNGAPI
# else
# define USE_MS_CRYPTOAPI # define USE_MS_CRYPTOAPI
# endif
#endif
// Define this to ensure C/C++ standard compliance and respect for GCC aliasing rules and other alignment fodder. If you // Define this to ensure C/C++ standard compliance and respect for GCC aliasing rules and other alignment fodder. If you
// experience a break with GCC at -O3, you should try this first. Guard it in case its set on the command line (and it differs). // experience a break with GCC at -O3, you should try this first. Guard it in case its set on the command line (and it differs).
@ -531,16 +548,31 @@ NAMESPACE_END
# define HIGHRES_TIMER_AVAILABLE # define HIGHRES_TIMER_AVAILABLE
#endif #endif
#ifdef CRYPTOPP_WIN32_AVAILABLE
# if !defined(WINAPI_FAMILY)
# define THREAD_TIMER_AVAILABLE
# elif defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define THREAD_TIMER_AVAILABLE
# endif
# endif
#endif
#ifdef CRYPTOPP_UNIX_AVAILABLE #ifdef CRYPTOPP_UNIX_AVAILABLE
# define HAS_BERKELEY_STYLE_SOCKETS # define HAS_BERKELEY_STYLE_SOCKETS
# define SOCKETS_AVAILABLE
#endif #endif
// Sockets are only available under Windows Runtime desktop partition apps (despite the MSDN literature)
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
# define HAS_WINDOWS_STYLE_SOCKETS # define HAS_WINDOWS_STYLE_SOCKETS
#endif # if !defined(WINAPI_FAMILY)
#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS))
# define SOCKETS_AVAILABLE # define SOCKETS_AVAILABLE
# elif defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define SOCKETS_AVAILABLE
# endif
# endif
#endif #endif
#if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) #if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS))
@ -549,15 +581,10 @@ NAMESPACE_END
# define USE_BERKELEY_STYLE_SOCKETS # define USE_BERKELEY_STYLE_SOCKETS
#endif #endif
#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) #if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(SOCKETS_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS)
# define WINDOWS_PIPES_AVAILABLE # define WINDOWS_PIPES_AVAILABLE
#endif #endif
#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI)
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
#endif
#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) #if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
# define NONBLOCKING_RNG_AVAILABLE # define NONBLOCKING_RNG_AVAILABLE
# define BLOCKING_RNG_AVAILABLE # define BLOCKING_RNG_AVAILABLE
@ -567,8 +594,24 @@ NAMESPACE_END
#endif #endif
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
# if !defined(WINAPI_FAMILY)
# define HAS_WINTHREADS # define HAS_WINTHREADS
# define THREADS_AVAILABLE # define THREADS_AVAILABLE
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# elif defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define HAS_WINTHREADS
# define THREADS_AVAILABLE
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# if ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/))
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# endif
# endif
# endif
#endif #endif
#endif // NO_OS_DEPENDENCE #endif // NO_OS_DEPENDENCE
@ -664,6 +707,19 @@ NAMESPACE_END
// C++11 or C++14 is available // C++11 or C++14 is available
#if defined(CRYPTOPP_CXX11) #if defined(CRYPTOPP_CXX11)
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; and Intel 13.0.
#if (CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)
# define CRYPTOPP_CXX11_ATOMICS 1
#elif defined(__clang__)
# if __has_feature(cxx_atomic)
# define CRYPTOPP_CXX11_ATOMICS 1
# endif
#elif (CRYPTOPP_GCC_VERSION >= 40400)
# define CRYPTOPP_CXX11_ATOMICS 1
#endif // atomics
// alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0. // alignof/alignas: MS at VS2013 (19.00); GCC at 4.8; Clang at 3.3; and Intel 15.0.
#if (CRYPTOPP_MSC_VERSION >= 1900) #if (CRYPTOPP_MSC_VERSION >= 1900)
# define CRYPTOPP_CXX11_ALIGNAS 1 # define CRYPTOPP_CXX11_ALIGNAS 1

View File

@ -1,6 +1,7 @@
// fipstest.cpp - written and placed in the public domain by Wei Dai // fipstest.cpp - written and placed in the public domain by Wei Dai
#include "pch.h" #include "pch.h"
#include "config.h"
#ifndef CRYPTOPP_IMPORTS #ifndef CRYPTOPP_IMPORTS
@ -11,8 +12,20 @@
#include "smartptr.h" #include "smartptr.h"
#include "misc.h" #include "misc.h"
// Simply disable CRYPTOPP_WIN32_AVAILABLE for Windows Phone and Windows Store apps
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
# if defined(WINAPI_FAMILY) && defined(WINAPI_FAMILY_PARTITION)
# if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# undef CRYPTOPP_WIN32_AVAILABLE
# endif
# endif
#endif
#ifdef CRYPTOPP_WIN32_AVAILABLE
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400 #define _WIN32_WINNT 0x0400
#endif
#include <windows.h> #include <windows.h>
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400

View File

@ -3,13 +3,24 @@
#include "pch.h" #include "pch.h"
#include "hrtimer.h" #include "hrtimer.h"
#include "misc.h" #include "misc.h"
#include <stddef.h> // for NULL #include <stddef.h> // for NULL
#include <time.h> #include <time.h>
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#elif defined(CRYPTOPP_UNIX_AVAILABLE) # if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# include <processthreadsapi.h>
# if defined(WINAPI_FAMILY)
# if (WINAPI_FAMILY_PARTITION(WINAPI_FAMILY_PHONE_APP))
# include <profileapi.h>
# endif
# endif
#endif
#endif
#if defined(CRYPTOPP_UNIX_AVAILABLE)
#include <sys/time.h> #include <sys/time.h>
#include <sys/times.h> #include <sys/times.h>
#include <unistd.h> #include <unistd.h>
@ -21,6 +32,22 @@ NAMESPACE_BEGIN(CryptoPP)
#ifndef CRYPTOPP_IMPORTS #ifndef CRYPTOPP_IMPORTS
#if defined(CRYPTOPP_WIN32_AVAILABLE)
inline TimerWord InitializePerformanceCounterFrequency()
{
LARGE_INTEGER freq = {0,0};
if (!QueryPerformanceFrequency(&freq))
throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
return freq.QuadPart;
}
inline TimerWord PerformanceCounterFrequency()
{
static const word64 freq = InitializePerformanceCounterFrequency();
return freq;
}
#endif
double TimerBase::ConvertTo(TimerWord t, Unit unit) double TimerBase::ConvertTo(TimerWord t, Unit unit)
{ {
static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000};
@ -81,14 +108,7 @@ TimerWord Timer::GetCurrentTimerValue()
TimerWord Timer::TicksPerSecond() TimerWord Timer::TicksPerSecond()
{ {
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE)
// Use the second union member to avoid an uninitialized warning return PerformanceCounterFrequency();
static LARGE_INTEGER freq = {0,0};
if (freq.QuadPart == 0)
{
if (!QueryPerformanceFrequency(&freq))
throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
}
return freq.QuadPart;
#elif defined(CRYPTOPP_UNIX_AVAILABLE) #elif defined(CRYPTOPP_UNIX_AVAILABLE)
return 1000000; return 1000000;
#else #else
@ -100,14 +120,14 @@ TimerWord Timer::TicksPerSecond()
TimerWord ThreadUserTimer::GetCurrentTimerValue() TimerWord ThreadUserTimer::GetCurrentTimerValue()
{ {
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(THREAD_TIMER_AVAILABLE)
static bool getCurrentThreadImplemented = true; static bool getCurrentThreadImplemented = true;
if (getCurrentThreadImplemented) if (getCurrentThreadImplemented)
{ {
FILETIME now, ignored; FILETIME now, ignored;
if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now)) if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
{ {
DWORD lastError = GetLastError(); const DWORD lastError = GetLastError();
if (lastError == ERROR_CALL_NOT_IMPLEMENTED) if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
{ {
getCurrentThreadImplemented = false; getCurrentThreadImplemented = false;
@ -119,6 +139,14 @@ TimerWord ThreadUserTimer::GetCurrentTimerValue()
} }
GetCurrentThreadNotImplemented: GetCurrentThreadNotImplemented:
return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC); return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
#elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE)
LARGE_INTEGER now;
if (!QueryPerformanceCounter(&now))
{
const DWORD lastError = GetLastError();
throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: QueryPerformanceCounter failed with error " + IntToString(lastError));
}
return now.QuadPart;
#elif defined(CRYPTOPP_UNIX_AVAILABLE) #elif defined(CRYPTOPP_UNIX_AVAILABLE)
tms now; tms now;
times(&now); times(&now);
@ -130,8 +158,11 @@ GetCurrentThreadNotImplemented:
TimerWord ThreadUserTimer::TicksPerSecond() TimerWord ThreadUserTimer::TicksPerSecond()
{ {
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(THREAD_TIMER_AVAILABLE)
return 10*1000*1000; return 10*1000*1000;
#elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE)
static const TimerWord ticksPerSecond = PerformanceCounterFrequency();
return ticksPerSecond;
#elif defined(CRYPTOPP_UNIX_AVAILABLE) #elif defined(CRYPTOPP_UNIX_AVAILABLE)
static const long ticksPerSecond = sysconf(_SC_CLK_TCK); static const long ticksPerSecond = sysconf(_SC_CLK_TCK);
return ticksPerSecond; return ticksPerSecond;

View File

@ -2,7 +2,8 @@
#define CRYPTOPP_HRTIMER_H #define CRYPTOPP_HRTIMER_H
#include "config.h" #include "config.h"
#ifndef HIGHRES_TIMER_AVAILABLE
#if !defined(HIGHRES_TIMER_AVAILABLE) || (defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE))
#include <time.h> #include <time.h>
#endif #endif
@ -14,7 +15,8 @@ NAMESPACE_BEGIN(CryptoPP)
typedef clock_t TimerWord; typedef clock_t TimerWord;
#endif #endif
//! _ //! \class TimerBase
//! \brief Base class for timers
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase
{ {
public: public:
@ -38,9 +40,11 @@ private:
TimerWord m_start, m_last; TimerWord m_start, m_last;
}; };
//! measure CPU time spent executing instructions of this thread (if supported by OS) //! \class ThreadUserTimer
/*! /note This only works correctly on Windows NT or later. On Unix it reports process time, and others wall clock time. //! \brief Measure CPU time spent executing instructions of this thread (if supported by OS)
*/ //! \note ThreadUserTimer only works correctly on Windows NT or later desktops and servers.
//! On Unix-based it reports process time. On Windows Phone and Windows Store it reports wall
//! clock time with performance counter precision. On all others it reports wall clock time.
class ThreadUserTimer : public TimerBase class ThreadUserTimer : public TimerBase
{ {
public: public:

34
misc.h
View File

@ -12,7 +12,7 @@
#if CRYPTOPP_MSC_VERSION #if CRYPTOPP_MSC_VERSION
# pragma warning(push) # pragma warning(push)
# pragma warning(disable: 4146) # pragma warning(disable: 4146 4514)
# if (CRYPTOPP_MSC_VERSION >= 1400) # if (CRYPTOPP_MSC_VERSION >= 1400)
# pragma warning(disable: 6326) # pragma warning(disable: 6326)
# endif # endif
@ -1070,6 +1070,36 @@ template<> inline void SecureWipeBuffer(word64 *buf, size_t n)
#endif // #if (_MSC_VER >= 1400 || defined(__GNUC__)) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) #endif // #if (_MSC_VER >= 1400 || defined(__GNUC__)) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)
#if (_MSC_VER >= 1700) && defined(_M_ARM)
template<> inline void SecureWipeBuffer(byte *buf, size_t n)
{
char *p = reinterpret_cast<char*>(buf+n);
while (n--)
__iso_volatile_store8(--p, 0);
}
template<> inline void SecureWipeBuffer(word16 *buf, size_t n)
{
short *p = reinterpret_cast<short*>(buf+n);
while (n--)
__iso_volatile_store16(--p, 0);
}
template<> inline void SecureWipeBuffer(word32 *buf, size_t n)
{
int *p = reinterpret_cast<int*>(buf+n);
while (n--)
__iso_volatile_store32(--p, 0);
}
template<> inline void SecureWipeBuffer(word64 *buf, size_t n)
{
__int64 *p = reinterpret_cast<__int64*>(buf+n);
while (n--)
__iso_volatile_store64(--p, 0);
}
#endif
//! \brief Sets each element of an array to 0 //! \brief Sets each element of an array to 0
//! \param buf an array of elements //! \param buf an array of elements
//! \param n the number of elements in the array //! \param n the number of elements in the array
@ -1858,7 +1888,7 @@ inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, co
inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock) inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
{ {
CRYPTOPP_UNUSED(order); CRYPTOPP_UNUSED(order);
block[0] = xorBlock ? (value ^ xorBlock[0]) : value; block[0] = (byte)(xorBlock ? (value ^ xorBlock[0]) : value);
} }
inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock) inline void UnalignedbyteNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)

View File

@ -3,14 +3,15 @@
#include "pch.h" #include "pch.h"
#include "network.h" #include "network.h"
#ifdef SOCKETS_AVAILABLE
#include "wait.h" #include "wait.h"
#define CRYPTOPP_TRACE_NETWORK 0 #define CRYPTOPP_TRACE_NETWORK 0
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#ifdef HIGHRES_TIMER_AVAILABLE
lword LimitedBandwidth::ComputeCurrentTransceiveLimit() lword LimitedBandwidth::ComputeCurrentTransceiveLimit()
{ {
if (!m_maxBytesPerSecond) if (!m_maxBytesPerSecond)
@ -548,6 +549,6 @@ lword NetworkSink::DoFlush(unsigned long maxTime, size_t targetSize)
return totalFlushSize; return totalFlushSize;
} }
#endif // #ifdef HIGHRES_TIMER_AVAILABLE
NAMESPACE_END NAMESPACE_END
#endif // #ifdef SOCKETS_AVAILABLE

View File

@ -3,12 +3,11 @@
#include "config.h" #include "config.h"
#ifdef HIGHRES_TIMER_AVAILABLE #ifdef SOCKETS_AVAILABLE
#include "filters.h" #include "filters.h"
#include "hrtimer.h" #include "hrtimer.h"
#include "stdcpp.h"
#include <deque>
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
@ -230,6 +229,6 @@ private:
NAMESPACE_END NAMESPACE_END
#endif // #ifdef HIGHRES_TIMER_AVAILABLE #endif // SOCKETS_AVAILABLE
#endif #endif // CRYPTOPP_NETWORK_H

116
osrng.cpp
View File

@ -3,21 +3,49 @@
// Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool. // Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool.
#include "pch.h" #include "pch.h"
#include "config.h"
#ifndef CRYPTOPP_IMPORTS #ifndef CRYPTOPP_IMPORTS
// Win32 has CryptoAPI and <wincrypt.h>. Windows 10 and Windows Store 10 have CNG and <bcrypt.h>.
// There's a hole for Windows Phone 8 and Windows Store 8. There is no userland crypto available.
// Also see http://stackoverflow.com/questions/36974545/random-numbers-for-windows-phone-8-and-windows-store-8
#if defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(OS_RNG_AVAILABLE)
# pragma message("WARNING: Compiling for Windows but an OS RNG is not available. This is likely a Windows Phone 8 or Windows Store 8 app.")
#endif
#if !defined(OS_NO_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
#include "osrng.h" #include "osrng.h"
#ifdef OS_RNG_AVAILABLE
#include "rng.h" #include "rng.h"
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
#ifndef _WIN32_WINNT //#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400 //#define _WIN32_WINNT 0x0400
#endif //#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#if defined(USE_MS_CRYPTOAPI)
#include <wincrypt.h> #include <wincrypt.h>
#ifndef CRYPT_NEWKEYSET
# define CRYPT_NEWKEYSET 0x00000008
#endif
#ifndef CRYPT_MACHINE_KEYSET
# define CRYPT_MACHINE_KEYSET 0x00000020
#endif
#elif defined(USE_MS_CNGAPI)
//#include <ntdef.h>
#include <bcrypt.h>
#ifndef BCRYPT_SUCCESS
# define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
#ifndef STATUS_INVALID_PARAMETER
# define STATUS_INVALID_PARAMETER 0xC000000D
#endif
#ifndef STATUS_INVALID_HANDLE
# define STATUS_INVALID_HANDLE 0xC0000008
#endif
#endif
#endif #endif
#ifdef CRYPTOPP_UNIX_AVAILABLE #ifdef CRYPTOPP_UNIX_AVAILABLE
@ -45,18 +73,62 @@ OS_RNG_Err::OS_RNG_Err(const std::string &operation)
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
MicrosoftCryptoProvider::MicrosoftCryptoProvider() #if defined(USE_MS_CNGAPI)
inline DWORD NtStatusToErrorCode(NTSTATUS status)
{ {
if (status == STATUS_INVALID_PARAMETER)
return ERROR_INVALID_PARAMETER;
else if (status == STATUS_INVALID_HANDLE)
return ERROR_INVALID_HANDLE;
else
return (DWORD)status;
}
#endif
#if defined(UNICODE) || defined(_UNICODE)
# define CRYPTOPP_CONTAINER L"Crypto++ RNG"
#else
# define CRYPTOPP_CONTAINER "Crypto++ RNG"
#endif
MicrosoftCryptoProvider::MicrosoftCryptoProvider() : m_hProvider(0)
{
#if defined(USE_MS_CRYPTOAPI)
// See http://support.microsoft.com/en-us/kb/238187 for CRYPT_NEWKEYSET fallback strategy
if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) if (!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
const DWORD firstErr = GetLastError();
if (!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET /*user*/) &&
!CryptAcquireContext(&m_hProvider, CRYPTOPP_CONTAINER, 0, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET|CRYPT_NEWKEYSET))
{
// Set original error with original code
SetLastError(firstErr);
throw OS_RNG_Err("CryptAcquireContext"); throw OS_RNG_Err("CryptAcquireContext");
} }
}
#elif defined(USE_MS_CNGAPI)
NTSTATUS ret = BCryptOpenAlgorithmProvider(&m_hProvider, BCRYPT_RNG_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
if (!(BCRYPT_SUCCESS(ret)))
{
// Hack... OS_RNG_Err calls GetLastError()
SetLastError(NtStatusToErrorCode(ret));
throw OS_RNG_Err("BCryptOpenAlgorithmProvider");
}
#endif
}
MicrosoftCryptoProvider::~MicrosoftCryptoProvider() MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
{ {
#if defined(USE_MS_CRYPTOAPI)
if (m_hProvider)
CryptReleaseContext(m_hProvider, 0); CryptReleaseContext(m_hProvider, 0);
#elif defined(USE_MS_CNGAPI)
if (m_hProvider)
BCryptCloseAlgorithmProvider(m_hProvider, 0);
#endif
} }
#endif #endif // CRYPTOPP_WIN32_AVAILABLE
NonblockingRng::NonblockingRng() NonblockingRng::NonblockingRng()
{ {
@ -77,16 +149,24 @@ NonblockingRng::~NonblockingRng()
void NonblockingRng::GenerateBlock(byte *output, size_t size) void NonblockingRng::GenerateBlock(byte *output, size_t size)
{ {
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
# ifdef WORKAROUND_MS_BUG_Q258000 // Acquiring a provider is expensive. Do it once and retain the reference.
const MicrosoftCryptoProvider &m_Provider = Singleton<MicrosoftCryptoProvider>().Ref(); static const MicrosoftCryptoProvider &hProvider = Singleton<MicrosoftCryptoProvider>().Ref();
# endif # if defined(USE_MS_CRYPTOAPI)
if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, output)) if (!CryptGenRandom(hProvider.GetProviderHandle(), (DWORD)size, output))
throw OS_RNG_Err("CryptGenRandom"); throw OS_RNG_Err("CryptGenRandom");
# elif defined(USE_MS_CNGAPI)
NTSTATUS ret = BCryptGenRandom(hProvider.GetProviderHandle(), output, (ULONG)size, 0);
if (!(BCRYPT_SUCCESS(ret)))
{
// Hack... OS_RNG_Err calls GetLastError()
SetLastError(NtStatusToErrorCode(ret));
throw OS_RNG_Err("BCryptGenRandom");
}
# endif
#else #else
while (size) while (size)
{ {
ssize_t len = read(m_fd, output, size); ssize_t len = read(m_fd, output, size);
if (len < 0) if (len < 0)
{ {
// /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well) // /dev/urandom reads CAN give EAGAIN errors! (maybe EINTR as well)
@ -99,10 +179,10 @@ void NonblockingRng::GenerateBlock(byte *output, size_t size)
output += len; output += len;
size -= len; size -= len;
} }
#endif #endif // CRYPTOPP_WIN32_AVAILABLE
} }
#endif #endif // NONBLOCKING_RNG_AVAILABLE
// ************************************************************* // *************************************************************
@ -151,7 +231,7 @@ void BlockingRng::GenerateBlock(byte *output, size_t size)
} }
} }
#endif #endif // BLOCKING_RNG_AVAILABLE
// ************************************************************* // *************************************************************
@ -187,6 +267,6 @@ void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize)
NAMESPACE_END NAMESPACE_END
#endif #endif // OS_RNG_AVAILABLE
#endif #endif // CRYPTOPP_IMPORTS

35
osrng.h
View File

@ -1,7 +1,6 @@
// osrng.h - written and placed in the public domain by Wei Dai // osrng.h - written and placed in the public domain by Wei Dai
//! \file //! \file osrng.h
//! \headerfile osrng.h
//! \brief Classes for access to the operating system's random number generators //! \brief Classes for access to the operating system's random number generators
#ifndef CRYPTOPP_OSRNG_H #ifndef CRYPTOPP_OSRNG_H
@ -9,7 +8,7 @@
#include "config.h" #include "config.h"
#ifdef OS_RNG_AVAILABLE #if !defined(OS_NO_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
#include "cryptlib.h" #include "cryptlib.h"
#include "randpool.h" #include "randpool.h"
@ -36,7 +35,7 @@ public:
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
//! \class MicrosoftCryptoProvider //! \class MicrosoftCryptoProvider
//! \brief Wrapper for Microsoft crypto service provider //! \brief Wrapper for Microsoft crypto service provider
//! \sa \def USE_MS_CRYPTOAPI, \def WORKAROUND_MS_BUG_Q258000 //! \sa \def USE_MS_CRYPTOAPI, \def USE_MS_CNGAPI, \def WORKAROUND_MS_BUG_Q258000
class CRYPTOPP_DLL MicrosoftCryptoProvider class CRYPTOPP_DLL MicrosoftCryptoProvider
{ {
public: public:
@ -44,7 +43,8 @@ public:
MicrosoftCryptoProvider(); MicrosoftCryptoProvider();
~MicrosoftCryptoProvider(); ~MicrosoftCryptoProvider();
// type HCRYPTPROV, avoid #include <windows.h> // type HCRYPTPROV and BCRYPT_ALG_HANDLE, avoid #include <windows.h>
#if defined(USE_MS_CRYPTOAPI)
# if defined(__CYGWIN__) && defined(__x86_64__) # if defined(__CYGWIN__) && defined(__x86_64__)
typedef unsigned long long ProviderHandle; typedef unsigned long long ProviderHandle;
# elif defined(WIN64) || defined(_WIN64) # elif defined(WIN64) || defined(_WIN64)
@ -52,26 +52,38 @@ public:
# else # else
typedef unsigned long ProviderHandle; typedef unsigned long ProviderHandle;
# endif # endif
#elif defined(USE_MS_CNGAPI)
typedef void *PVOID;
typedef PVOID ProviderHandle;
#endif // USE_MS_CRYPTOAPI or USE_MS_CNGAPI
//! \brief Retrieves the CryptoAPI provider handle //! \brief Retrieves the provider handle
//! \returns CryptoAPI provider handle //! \returns CryptoAPI provider handle
//! \details The handle is acquired by a call to CryptAcquireContext(). //! \details If USE_MS_CRYPTOAPI is in effect, then CryptAcquireContext()
//! CryptReleaseContext() is called upon destruction. //! acquires then handle and CryptReleaseContext() releases the handle
//! upon destruction. If USE_MS_CNGAPI is in effect, then
//! BCryptOpenAlgorithmProvider() acquires then handle and
//! BCryptCloseAlgorithmProvider() releases the handle upon destruction.
ProviderHandle GetProviderHandle() const {return m_hProvider;} ProviderHandle GetProviderHandle() const {return m_hProvider;}
private: private:
ProviderHandle m_hProvider; ProviderHandle m_hProvider;
}; };
#if defined(_MSC_VER) #if defined(_MSC_VER) && defined(USE_MS_CRYPTOAPI)
# pragma comment(lib, "advapi32.lib") # pragma comment(lib, "advapi32.lib")
#endif #endif
#if defined(_MSC_VER) && defined(USE_MS_CNGAPI)
# pragma comment(lib, "bcrypt.lib")
#endif
#endif //CRYPTOPP_WIN32_AVAILABLE #endif //CRYPTOPP_WIN32_AVAILABLE
//! \class NonblockingRng //! \class NonblockingRng
//! \brief Wrapper class for /dev/random and /dev/srandom //! \brief Wrapper class for /dev/random and /dev/srandom
//! \details Encapsulates CryptoAPI's CryptGenRandom() on Windows, or /dev/urandom on Unix and compatibles. //! \details Encapsulates CryptoAPI's CryptGenRandom() or CryptoNG's BCryptGenRandom()
//! on Windows, or /dev/urandom on Unix and compatibles.
class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
{ {
public: public:
@ -87,9 +99,7 @@ public:
protected: protected:
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
# ifndef WORKAROUND_MS_BUG_Q258000
MicrosoftCryptoProvider m_Provider; MicrosoftCryptoProvider m_Provider;
# endif
#else #else
int m_fd; int m_fd;
#endif #endif
@ -137,6 +147,7 @@ CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *outpu
//! \class AutoSeededRandomPool //! \class AutoSeededRandomPool
//! \brief Automatically Seeded Randomness Pool //! \brief Automatically Seeded Randomness Pool
//! \details This class seeds itself using an operating system provided RNG. //! \details This class seeds itself using an operating system provided RNG.
//! AutoSeededRandomPool was suggested by Leonard Janke.
class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
{ {
public: public:

View File

@ -1,19 +1,21 @@
// socketft.cpp - written and placed in the public domain by Wei Dai // socketft.cpp - written and placed in the public domain by Wei Dai
#include "pch.h" #include "pch.h"
#include "config.h"
#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE)
// TODO: http://github.com/weidai11/cryptopp/issues/19 // TODO: http://github.com/weidai11/cryptopp/issues/19
#define _WINSOCK_DEPRECATED_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "socketft.h" #include "socketft.h"
#ifdef SOCKETS_AVAILABLE
#include "wait.h" #include "wait.h"
// Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h> // Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h> and <ioapiset.h>
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE)
# if defined(_WIN32_WINNT_WIN8) && ((WINVER >= _WIN32_WINNT_WIN8) || (_WIN32_WINNT >= _WIN32_WINNT_WIN8)) # if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# include <synchapi.h> # include <synchapi.h>
# include <ioapiset.h>
# define USE_WINDOWS8_API
# endif # endif
#endif #endif
@ -103,8 +105,15 @@ void Socket::CloseSocket()
if (m_s != INVALID_SOCKET) if (m_s != INVALID_SOCKET)
{ {
#ifdef USE_WINDOWS_STYLE_SOCKETS #ifdef USE_WINDOWS_STYLE_SOCKETS
CancelIo((HANDLE) m_s); # if defined(USE_WINDOWS8_API)
BOOL result = CancelIoEx((HANDLE) m_s, NULL);
assert(result || (!result && GetLastError() == ERROR_NOT_FOUND));
CheckAndHandleError_int("closesocket", closesocket(m_s)); CheckAndHandleError_int("closesocket", closesocket(m_s));
# else
BOOL result = CancelIo((HANDLE) m_s);
assert(result || (!result && GetLastError() == ERROR_NOT_FOUND));
CheckAndHandleError_int("closesocket", closesocket(m_s));
# endif
#else #else
CheckAndHandleError_int("close", close(m_s)); CheckAndHandleError_int("close", close(m_s));
#endif #endif
@ -356,7 +365,13 @@ SocketReceiver::SocketReceiver(Socket &s)
SocketReceiver::~SocketReceiver() SocketReceiver::~SocketReceiver()
{ {
#ifdef USE_WINDOWS_STYLE_SOCKETS #ifdef USE_WINDOWS_STYLE_SOCKETS
CancelIo((HANDLE) m_s.GetSocket()); # if defined(USE_WINDOWS8_API)
BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULL);
assert(result || (!result && GetLastError() == ERROR_NOT_FOUND));
# else
BOOL result = CancelIo((HANDLE) m_s.GetSocket());
assert(result || (!result && GetLastError() == ERROR_NOT_FOUND));
# endif
#endif #endif
} }
@ -438,7 +453,13 @@ SocketSender::SocketSender(Socket &s)
SocketSender::~SocketSender() SocketSender::~SocketSender()
{ {
#ifdef USE_WINDOWS_STYLE_SOCKETS #ifdef USE_WINDOWS_STYLE_SOCKETS
CancelIo((HANDLE) m_s.GetSocket()); # if defined(USE_WINDOWS8_API)
BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULL);
assert(result || (!result && GetLastError() == ERROR_NOT_FOUND));
# else
BOOL result = CancelIo((HANDLE) m_s.GetSocket());
assert(result || (!result && GetLastError() == ERROR_NOT_FOUND));
# endif
#endif #endif
} }
@ -559,8 +580,8 @@ void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack cons
container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack)); container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack));
} }
#endif #endif // USE_BERKELEY_STYLE_SOCKETS
NAMESPACE_END NAMESPACE_END
#endif // #ifdef SOCKETS_AVAILABLE #endif // SOCKETS_AVAILABLE

View File

@ -1,7 +1,9 @@
#ifndef CRYPTOPP_SOCKETFT_H #ifndef CRYPTOPP_SOCKETFT_H
#define CRYPTOPP_SOCKETFT_H #define CRYPTOPP_SOCKETFT_H
#ifdef SOCKETS_AVAILABLE #include "config.h"
#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE)
#include "cryptlib.h" #include "cryptlib.h"
#include "network.h" #include "network.h"
@ -218,6 +220,6 @@ private:
NAMESPACE_END NAMESPACE_END
#endif // #ifdef SOCKETS_AVAILABLE #endif // SOCKETS_AVAILABLE
#endif #endif // CRYPTOPP_SOCKETFT_H

View File

@ -32,6 +32,10 @@ namespace std {
#include <iterator> #include <iterator>
#endif #endif
#if defined(CRYPTOPP_CXX11_ATOMICS)
#include <atomic>
#endif
#include <cstdlib> #include <cstdlib>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>

View File

@ -802,6 +802,9 @@ void HexDecode(const char *in, const char *out)
void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName) void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName)
{ {
// Quiet warnings for Windows Phone and Windows Store builds
CRYPTOPP_UNUSED(sourcePortName), CRYPTOPP_UNUSED(destinationHost), CRYPTOPP_UNUSED(destinationPortName);
#ifdef SOCKETS_AVAILABLE #ifdef SOCKETS_AVAILABLE
SocketsInitializer sockInit; SocketsInitializer sockInit;

6
trap.h
View File

@ -18,7 +18,11 @@
# include <sstream> # include <sstream>
# if defined(CRYPTOPP_WIN32_AVAILABLE) # if defined(CRYPTOPP_WIN32_AVAILABLE)
# pragma push_macro("WIN32_LEAN_AND_MEAN") # pragma push_macro("WIN32_LEAN_AND_MEAN")
# pragma push_macro("_WIN32_WINNT")
# pragma push_macro("NOMINMAX")
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
# define _WIN32_WINNT 0x0400
# define NOMINMAX
# include <Windows.h> # include <Windows.h>
# elif defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE) # elif defined(CRYPTOPP_BSD_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)
# include <signal.h> # include <signal.h>
@ -60,6 +64,8 @@
#if defined(CRYPTOPP_DEBUG) && defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_DEBUG) && defined(CRYPTOPP_WIN32_AVAILABLE)
# pragma pop_macro("WIN32_LEAN_AND_MEAN") # pragma pop_macro("WIN32_LEAN_AND_MEAN")
# pragma pop_macro("_WIN32_WINNT")
# pragma pop_macro("NOMINMAX")
#endif #endif
#endif // CRYPTOPP_TRAP_H #endif // CRYPTOPP_TRAP_H

View File

@ -9,7 +9,8 @@
#endif #endif
#ifndef CRYPTOPP_IMPORTS #ifndef CRYPTOPP_IMPORTS
#ifdef THREADS_AVAILABLE
#if !defined(NO_OS_DEPENDENCE) && defined(THREADS_AVAILABLE)
#include "trdlocal.h" #include "trdlocal.h"
@ -101,5 +102,5 @@ void *ThreadLocalStorage::GetValue() const
NAMESPACE_END NAMESPACE_END
#endif // #ifdef THREADS_AVAILABLE #endif // THREADS_AVAILABLE
#endif #endif // CRYPTOPP_IMPORTS

View File

@ -3,7 +3,7 @@
#include "config.h" #include "config.h"
#ifdef THREADS_AVAILABLE #if !defined(NO_OS_DEPENDENCE) && defined(THREADS_AVAILABLE)
#include "misc.h" #include "misc.h"
@ -39,6 +39,6 @@ private:
NAMESPACE_END NAMESPACE_END
#endif // #ifdef THREADS_AVAILABLE #endif // THREADS_AVAILABLE
#endif #endif // CRYPTOPP_TRDLOCAL_H

View File

@ -906,7 +906,7 @@ bool TestOS_RNG()
return pass; return pass;
} }
#ifdef NO_OS_DEPENDENCE #if defined(NO_OS_DEPENDENCE) || !defined(OS_RNG_AVAILABLE)
bool TestAutoSeeded() bool TestAutoSeeded()
{ {
return true; return true;

View File

@ -7,16 +7,18 @@
# pragma warning(disable: 4189) # pragma warning(disable: 4189)
#endif #endif
#if !defined(NO_OS_DEPENDENCE) && (defined(SOCKETS_AVAILABLE) || defined(WINDOWS_PIPES_AVAILABLE))
#include "wait.h" #include "wait.h"
#include "misc.h" #include "misc.h"
#include "smartptr.h" #include "smartptr.h"
#ifdef SOCKETS_AVAILABLE // Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h> and <ioapiset.h>
// Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h>
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE)
# if defined(_WIN32_WINNT_WIN8) && ((WINVER >= _WIN32_WINNT_WIN8) || (_WIN32_WINNT >= _WIN32_WINNT_WIN8)) # if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# include <synchapi.h> # include <synchapi.h>
# include <ioapiset.h>
# define USE_WINDOWS8_API
# endif # endif
#endif #endif
@ -153,8 +155,13 @@ WaitObjectContainer::~WaitObjectContainer()
assert(bResult != 0); CRYPTOPP_UNUSED(bResult); assert(bResult != 0); CRYPTOPP_UNUSED(bResult);
// Enterprise Analysis warning // Enterprise Analysis warning
#if defined(USE_WINDOWS8_API)
DWORD dwResult = ::WaitForMultipleObjectsEx((DWORD)m_threads.size(), threadHandles, TRUE, INFINITE, FALSE);
assert((dwResult >= WAIT_OBJECT_0) && (dwResult < (DWORD)m_threads.size()));
#else
DWORD dwResult = ::WaitForMultipleObjects((DWORD)m_threads.size(), threadHandles, TRUE, INFINITE); DWORD dwResult = ::WaitForMultipleObjects((DWORD)m_threads.size(), threadHandles, TRUE, INFINITE);
assert((dwResult >= WAIT_OBJECT_0) && (dwResult < (DWORD)m_threads.size())); assert((dwResult >= WAIT_OBJECT_0) && (dwResult < (DWORD)m_threads.size()));
#endif
for (i=0; i<m_threads.size(); i++) for (i=0; i<m_threads.size(); i++)
{ {
@ -192,8 +199,13 @@ DWORD WINAPI WaitingThread(LPVOID lParam)
while (true) while (true)
{ {
thread.waitingToWait = true; thread.waitingToWait = true;
#if defined(USE_WINDOWS8_API)
DWORD result = ::WaitForSingleObjectEx(thread.startWaiting, INFINITE, FALSE);
assert(result != WAIT_FAILED);
#else
DWORD result = ::WaitForSingleObject(thread.startWaiting, INFINITE); DWORD result = ::WaitForSingleObject(thread.startWaiting, INFINITE);
assert(result != WAIT_FAILED); assert(result != WAIT_FAILED);
#endif
thread.waitingToWait = false; thread.waitingToWait = false;
if (thread.terminate) if (thread.terminate)
@ -205,8 +217,13 @@ DWORD WINAPI WaitingThread(LPVOID lParam)
handles[0] = thread.stopWaiting; handles[0] = thread.stopWaiting;
std::copy(thread.waitHandles, thread.waitHandles+thread.count, handles.begin()+1); std::copy(thread.waitHandles, thread.waitHandles+thread.count, handles.begin()+1);
#if defined(USE_WINDOWS8_API)
result = ::WaitForMultipleObjectsEx((DWORD)handles.size(), &handles[0], FALSE, INFINITE, FALSE);
assert(result != WAIT_FAILED);
#else
result = ::WaitForMultipleObjects((DWORD)handles.size(), &handles[0], FALSE, INFINITE); result = ::WaitForMultipleObjects((DWORD)handles.size(), &handles[0], FALSE, INFINITE);
assert(result != WAIT_FAILED); assert(result != WAIT_FAILED);
#endif
if (result == WAIT_OBJECT_0) if (result == WAIT_OBJECT_0)
continue; // another thread finished waiting first, so do nothing continue; // another thread finished waiting first, so do nothing
@ -309,8 +326,13 @@ bool WaitObjectContainer::Wait(unsigned long milliseconds)
ResetEvent(m_stopWaiting); ResetEvent(m_stopWaiting);
PulseEvent(m_startWaiting); PulseEvent(m_startWaiting);
#if defined(USE_WINDOWS8_API)
DWORD result = ::WaitForSingleObjectEx(m_stopWaiting, milliseconds, FALSE);
assert(result != WAIT_FAILED);
#else
DWORD result = ::WaitForSingleObject(m_stopWaiting, milliseconds); DWORD result = ::WaitForSingleObject(m_stopWaiting, milliseconds);
assert(result != WAIT_FAILED); assert(result != WAIT_FAILED);
#endif
if (result == WAIT_OBJECT_0) if (result == WAIT_OBJECT_0)
{ {
@ -335,7 +357,13 @@ bool WaitObjectContainer::Wait(unsigned long milliseconds)
static unsigned long lastTime = 0; static unsigned long lastTime = 0;
unsigned long timeBeforeWait = t.ElapsedTime(); unsigned long timeBeforeWait = t.ElapsedTime();
#endif #endif
#if defined(USE_WINDOWS8_API)
DWORD result = ::WaitForMultipleObjectsEx((DWORD)m_handles.size(), &m_handles[0], FALSE, milliseconds, FALSE);
assert(result != WAIT_FAILED);
#else
DWORD result = ::WaitForMultipleObjects((DWORD)m_handles.size(), &m_handles[0], FALSE, milliseconds); DWORD result = ::WaitForMultipleObjects((DWORD)m_handles.size(), &m_handles[0], FALSE, milliseconds);
assert(result != WAIT_FAILED);
#endif
#if TRACE_WAIT #if TRACE_WAIT
if (milliseconds > 0) if (milliseconds > 0)
{ {

5
wait.h
View File

@ -4,12 +4,13 @@
#define CRYPTOPP_WAIT_H #define CRYPTOPP_WAIT_H
#include "config.h" #include "config.h"
#if !defined(NO_OS_DEPENDENCE) && (defined(SOCKETS_AVAILABLE) || defined(WINDOWS_PIPES_AVAILABLE))
#include "cryptlib.h" #include "cryptlib.h"
#include "misc.h" #include "misc.h"
#include "stdcpp.h" #include "stdcpp.h"
#ifdef SOCKETS_AVAILABLE
#ifdef USE_WINDOWS_STYLE_SOCKETS #ifdef USE_WINDOWS_STYLE_SOCKETS
#include <winsock2.h> #include <winsock2.h>
#else #else

View File

@ -1,16 +1,19 @@
// winpipes.cpp - written and placed in the public domain by Wei Dai // winpipes.cpp - written and placed in the public domain by Wei Dai
#include "pch.h" #include "pch.h"
#include "config.h"
#if !defined(NO_OS_DEPENDENCE) && defined(WINDOWS_PIPES_AVAILABLE)
#include "winpipes.h" #include "winpipes.h"
#ifdef WINDOWS_PIPES_AVAILABLE
#include "wait.h" #include "wait.h"
// Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h> // Windows 8, Windows Server 2012, and Windows Phone 8.1 need <synchapi.h> and <ioapiset.h>
#if defined(CRYPTOPP_WIN32_AVAILABLE) #if defined(CRYPTOPP_WIN32_AVAILABLE)
# if defined(_WIN32_WINNT_WIN8) && ((WINVER >= _WIN32_WINNT_WIN8) || (_WIN32_WINNT >= _WIN32_WINNT_WIN8)) # if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# include <synchapi.h> # include <synchapi.h>
# include <ioapiset.h>
# define USE_WINDOWS8_API
# endif # endif
#endif #endif
@ -135,8 +138,12 @@ unsigned int WindowsPipeReceiver::GetReceiveResult()
{ {
if (m_resultPending) if (m_resultPending)
{ {
const HANDLE h = GetHandle(); #if defined(USE_WINDOWS8_API)
if (GetOverlappedResult(h, &m_overlapped, &m_lastResult, false)) BOOL result = GetOverlappedResultEx(GetHandle(), &m_overlapped, &m_lastResult, INFINITE, FALSE);
#else
BOOL result = GetOverlappedResult(GetHandle(), &m_overlapped, &m_lastResult, FALSE);
#endif
if (result)
{ {
if (m_lastResult == 0) if (m_lastResult == 0)
m_eofReceived = true; m_eofReceived = true;
@ -201,8 +208,13 @@ unsigned int WindowsPipeSender::GetSendResult()
if (m_resultPending) if (m_resultPending)
{ {
const HANDLE h = GetHandle(); const HANDLE h = GetHandle();
BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, false); #if defined(USE_WINDOWS8_API)
BOOL result = GetOverlappedResultEx(h, &m_overlapped, &m_lastResult, INFINITE, FALSE);
CheckAndHandleError("GetOverlappedResultEx", result);
#else
BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, FALSE);
CheckAndHandleError("GetOverlappedResult", result); CheckAndHandleError("GetOverlappedResult", result);
#endif
m_resultPending = false; m_resultPending = false;
} }
return m_lastResult; return m_lastResult;

View File

@ -1,7 +1,9 @@
#ifndef CRYPTOPP_WINPIPES_H #ifndef CRYPTOPP_WINPIPES_H
#define CRYPTOPP_WINPIPES_H #define CRYPTOPP_WINPIPES_H
#ifdef WINDOWS_PIPES_AVAILABLE #include "config.h"
#if !defined(NO_OS_DEPENDENCE) && defined(WINDOWS_PIPES_AVAILABLE)
#include "cryptlib.h" #include "cryptlib.h"
#include "network.h" #include "network.h"
@ -10,7 +12,7 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
//! Windows Handle //! \brief Windows Handle
class WindowsHandle class WindowsHandle
{ {
public: public:
@ -35,7 +37,7 @@ protected:
bool m_own; bool m_own;
}; };
//! Windows Pipe //! \brief Windows Pipe
class WindowsPipe class WindowsPipe
{ {
public: public:
@ -56,7 +58,7 @@ protected:
{assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);}
}; };
//! pipe-based implementation of NetworkReceiver //! \brief Pipe-based implementation of NetworkReceiver
class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver
{ {
public: public:
@ -79,7 +81,7 @@ private:
bool m_eofReceived; bool m_eofReceived;
}; };
//! pipe-based implementation of NetworkSender //! \brief Pipe-based implementation of NetworkSender
class WindowsPipeSender : public WindowsPipe, public NetworkSender class WindowsPipeSender : public WindowsPipe, public NetworkSender
{ {
public: public:
@ -102,7 +104,7 @@ private:
DWORD m_lastResult; DWORD m_lastResult;
}; };
//! Windows Pipe Source //! \brief Windows Pipe Source
class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver
{ {
public: public:
@ -121,7 +123,7 @@ private:
NetworkReceiver & AccessReceiver() {return *this;} NetworkReceiver & AccessReceiver() {return *this;}
}; };
//! Windows Pipe Sink //! \brief Windows Pipe Sink
class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender
{ {
public: public: