@@ -1772,6 +1772,42 @@ 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 ;
1782+ import core.sys.windows.wincrypt ;
1783+
1784+ HCRYPTPROV wincryptHandle;
1785+
1786+ const gotHandle = CryptAcquireContext(
1787+ &wincryptHandle,
1788+ null ,
1789+ MS_STRONG_PROV .ptr,
1790+ PROV_RSA_FULL ,
1791+ CRYPT_VERIFYCONTEXT ,
1792+ );
1793+ if (! gotHandle)
1794+ return false ;
1795+
1796+ scope (exit)
1797+ if (! CryptReleaseContext(wincryptHandle, 0 )) { /* ignore */ }
1798+
1799+ const gotRandom = CryptGenRandom(
1800+ wincryptHandle,
1801+ DWORD (T.sizeof),
1802+ cast (ubyte * ) &result,
1803+ );
1804+ if (! gotRandom)
1805+ return false ;
1806+
1807+ return true ;
1808+ }
1809+ }
1810+
17751811/**
17761812A "good" seed for initializing random number engines. Initializing
17771813with $(D_PARAM unpredictableSeed) makes engines generate different
@@ -1788,7 +1824,19 @@ how excellent the source of entropy is.
17881824*/
17891825@property uint unpredictableSeed() @trusted nothrow @nogc
17901826{
1791- version (AnyARC4Random)
1827+ version (Windows )
1828+ {
1829+ uint result;
1830+ if (! wincryptGenRandom! uint (result))
1831+ {
1832+ version (none )
1833+ return fallbackSeed ();
1834+ else
1835+ assert (false , " CryptAcquireContext() or CryptGenRandom() failed." );
1836+ }
1837+ return result;
1838+ }
1839+ else version (AnyARC4Random)
17921840 {
17931841 return arc4random ();
17941842 }
@@ -1837,7 +1885,19 @@ if (isUnsigned!UIntType)
18371885 // / ditto
18381886 @property UIntType unpredictableSeed() @nogc nothrow @trusted
18391887 {
1840- version (AnyARC4Random)
1888+ version (Windows )
1889+ {
1890+ UIntType result;
1891+ if (! wincryptGenRandom! UIntType(result))
1892+ {
1893+ version (none )
1894+ return fallbackSeed ();
1895+ else
1896+ assert (false , " CryptAcquireContext() or CryptGenRandom() failed." );
1897+ }
1898+ return result;
1899+ }
1900+ else version (AnyARC4Random)
18411901 {
18421902 static if (UIntType.sizeof <= uint .sizeof)
18431903 {
0 commit comments