diff options
Diffstat (limited to 'llvm/lib/Support/Windows/Process.inc')
-rw-r--r-- | llvm/lib/Support/Windows/Process.inc | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc index 3526e3dee6fa1..8064d4e17b295 100644 --- a/llvm/lib/Support/Windows/Process.inc +++ b/llvm/lib/Support/Windows/Process.inc @@ -19,7 +19,7 @@ #include <malloc.h> // The Windows.h header must be after LLVM and standard headers. -#include "WindowsSupport.h" +#include "llvm/Support/Windows/WindowsSupport.h" #include <direct.h> #include <io.h> @@ -43,6 +43,12 @@ using namespace llvm; +Process::Pid Process::getProcessId() { + static_assert(sizeof(Pid) >= sizeof(DWORD), + "Process::Pid should be big enough to store DWORD"); + return Pid(::GetCurrentProcessId()); +} + // This function retrieves the page size using GetNativeSystemInfo() and is // present solely so it can be called once to initialize the self_process member // below. @@ -439,18 +445,38 @@ const char *Process::ResetColor() { return 0; } +static unsigned GetRandomNumberSeed() { + // Generate a random number seed from the millisecond-resolution Windows + // system clock and the current process id. + FILETIME Time; + GetSystemTimeAsFileTime(&Time); + DWORD Pid = GetCurrentProcessId(); + return hash_combine(Time.dwHighDateTime, Time.dwLowDateTime, Pid); +} + +static unsigned GetPseudoRandomNumber() { + // Arrange to call srand once when this function is first used, and + // otherwise (if GetRandomNumber always succeeds in using + // CryptGenRandom) don't bother at all. + static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0); + (void)x; + return ::rand(); +} + unsigned Process::GetRandomNumber() { + // Try to use CryptGenRandom. HCRYPTPROV HCPC; - if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) - ReportLastErrorFatal("Could not acquire a cryptographic context"); - - ScopedCryptContext CryptoProvider(HCPC); - unsigned Ret; - if (!::CryptGenRandom(CryptoProvider, sizeof(Ret), - reinterpret_cast<BYTE *>(&Ret))) - ReportLastErrorFatal("Could not generate a random number"); - return Ret; + if (::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + ScopedCryptContext CryptoProvider(HCPC); + unsigned Ret; + if (::CryptGenRandom(CryptoProvider, sizeof(Ret), + reinterpret_cast<BYTE *>(&Ret))) + return Ret; + } + + // If that fails, fall back to pseudo-random numbers. + return GetPseudoRandomNumber(); } typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW); |