@@ -1772,6 +1772,49 @@ else
17721772 }
17731773}
17741774
1775+ version (Windows )
1776+ {
1777+ pragma (lib, " advapi32.lib" ); // `std.registry` does so, too.
1778+
1779+ private bool wincryptGenRandom (T)(out T result) @trusted
1780+ {
1781+ import core.sys.windows.windef : DWORD , PBYTE ;
1782+ import core.sys.windows.wincrypt :
1783+ CryptAcquireContext,
1784+ CryptGenRandom,
1785+ CryptReleaseContext,
1786+ CRYPT_VERIFYCONTEXT ,
1787+ HCRYPTPROV ,
1788+ MS_STRONG_PROV ,
1789+ PROV_RSA_FULL ;
1790+
1791+ HCRYPTPROV wincryptHandle;
1792+
1793+ const gotHandle = CryptAcquireContext(
1794+ &wincryptHandle,
1795+ null ,
1796+ MS_STRONG_PROV .ptr,
1797+ PROV_RSA_FULL ,
1798+ CRYPT_VERIFYCONTEXT ,
1799+ );
1800+ if (! gotHandle)
1801+ return false ;
1802+
1803+ scope (exit)
1804+ if (! CryptReleaseContext(wincryptHandle, 0 )) { /* ignore */ }
1805+
1806+ const gotRandom = CryptGenRandom(
1807+ wincryptHandle,
1808+ DWORD (T.sizeof),
1809+ cast (PBYTE ) &result,
1810+ );
1811+ if (! gotRandom)
1812+ return false ;
1813+
1814+ return true ;
1815+ }
1816+ }
1817+
17751818/**
17761819A "good" seed for initializing random number engines. Initializing
17771820with $(D_PARAM unpredictableSeed) makes engines generate different
@@ -1788,7 +1831,19 @@ how excellent the source of entropy is.
17881831*/
17891832@property uint unpredictableSeed() @trusted nothrow @nogc
17901833{
1791- version (AnyARC4Random)
1834+ version (Windows )
1835+ {
1836+ uint result;
1837+ if (! wincryptGenRandom! uint (result))
1838+ {
1839+ version (none )
1840+ return fallbackSeed ();
1841+ else
1842+ assert (false , " CryptAcquireContext() or CryptGenRandom() failed." );
1843+ }
1844+ return result;
1845+ }
1846+ else version (AnyARC4Random)
17921847 {
17931848 return arc4random ();
17941849 }
@@ -1837,7 +1892,19 @@ if (isUnsigned!UIntType)
18371892 // / ditto
18381893 @property UIntType unpredictableSeed() @nogc nothrow @trusted
18391894 {
1840- version (AnyARC4Random)
1895+ version (Windows )
1896+ {
1897+ UIntType result;
1898+ if (! wincryptGenRandom! UIntType(result))
1899+ {
1900+ version (none )
1901+ return fallbackSeed ();
1902+ else
1903+ assert (false , " CryptAcquireContext() or CryptGenRandom() failed." );
1904+ }
1905+ return result;
1906+ }
1907+ else version (AnyARC4Random)
18411908 {
18421909 static if (UIntType.sizeof <= uint .sizeof)
18431910 {
0 commit comments