| module std.internal.windows.bcrypt; | |
| version (Windows): | |
| import core.sys.windows.bcrypt : BCryptGenRandom, BCRYPT_USE_SYSTEM_PREFERRED_RNG; | |
| import core.sys.windows.windef : HMODULE, PUCHAR, ULONG; | |
| import core.sys.windows.ntdef : NT_SUCCESS; | |
| pragma(lib, "Bcrypt.lib"); | |
| package(std) bool bcryptGenRandom(T)(out T result) @trusted | |
| { | |
| loadBcrypt(); | |
| const gotRandom = ptrBCryptGenRandom( | |
| null, | |
| cast(PUCHAR) &result, | |
| ULONG(T.sizeof), | |
| BCRYPT_USE_SYSTEM_PREFERRED_RNG, | |
| ); | |
| return NT_SUCCESS(gotRandom); | |
| } | |
| private | |
| { | |
| HMODULE hBcrypt = null; | |
| typeof(BCryptGenRandom)* ptrBCryptGenRandom; | |
| } | |
| private void loadBcrypt() @nogc nothrow | |
| { | |
| import core.sys.windows.winbase : GetProcAddress, LoadLibraryA; | |
| if (!hBcrypt) | |
| { | |
| hBcrypt = LoadLibraryA("Bcrypt.dll"); | |
| if (!hBcrypt) | |
| assert(false, `LoadLibraryA("Bcrypt.dll") failed.`); // `@nogc` | |
| ptrBCryptGenRandom = cast(typeof(ptrBCryptGenRandom)) GetProcAddress(hBcrypt , "BCryptGenRandom"); | |
| if (!ptrBCryptGenRandom) | |
| assert(false, `GetProcAddress(hBcrypt , "BCryptGenRandom") failed.`); // `@nogc` | |
| } | |
| } | |
| // Will free `Bcrypt.dll`. | |
| private void freeBcrypt() @nogc nothrow | |
| { | |
| import core.sys.windows.winbase : FreeLibrary; | |
| if (hBcrypt) | |
| { | |
| if (!FreeLibrary(hBcrypt)) | |
| assert(false, `FreeLibrary("Bcrypt.dll") failed.`); // `@nogc` | |
| hBcrypt = null; | |
| ptrBCryptGenRandom = null; | |
| } | |
| } | |
| static ~this() | |
| { | |
| freeBcrypt(); | |
| } |