Beispiel #1
0
errno_t __cdecl rand_s
(
    unsigned int* _RandomValue
) {
    PGENRANDOM pfnRtlGenRandom = _decode_pointer(g_pfnRtlGenRandom);
    _VALIDATE_RETURN_ERRCODE(_RandomValue != NULL, EINVAL);
    *_RandomValue = 0; // Review : better value to initialize it to?

    if (pfnRtlGenRandom == NULL) {
        PGENRANDOM encoded;
        void* enull;
        // Advapi32.dll is unloaded when the App exits.
        HMODULE hAdvApi32 = LoadLibrary("ADVAPI32.DLL");

        if (!hAdvApi32) {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), EINVAL);
        }

        pfnRtlGenRandom = (PGENRANDOM) GetProcAddress(hAdvApi32, _TO_STR(RtlGenRandom));

        if (pfnRtlGenRandom == NULL) {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), _get_errno_from_oserr(GetLastError()));
        }

        encoded = (PGENRANDOM) _encode_pointer(pfnRtlGenRandom);
        enull = _encoded_null();
#ifdef _M_IX86

        if ((void*)(LONG_PTR)InterlockedExchange(
                    (LONG*)&g_pfnRtlGenRandom,
                    (LONG)(LONG_PTR)encoded)
                != enull)
#else  /* _M_IX86 */
        if (InterlockedExchangePointer(
                    (void**)&g_pfnRtlGenRandom,
                    (void*)encoded)
                != enull)
#endif  /* _M_IX86 */
        {
            /* A different thread has already loaded advapi32.dll. */
            FreeLibrary(hAdvApi32);
        }
    }

    if (!(*pfnRtlGenRandom)(_RandomValue, (ULONG)sizeof(unsigned int))) {
        errno = ENOMEM;
        return errno;
    }

    return 0;
}
errno_t __cdecl rand_s
(
    unsigned int *_RandomValue
)
{
    PGENRANDOM pfnRtlGenRandom = (PGENRANDOM) DecodePointer(g_pfnRtlGenRandom);
    _VALIDATE_RETURN_ERRCODE( _RandomValue != NULL, EINVAL );
    *_RandomValue = 0; // Review : better value to initialize it to?

    if ( pfnRtlGenRandom == NULL )
    {
        PGENRANDOM encoded;
        void* enull;
#ifdef _CORESYS
#define RAND_DLL L"cryptbase.dll"
#else  /* _CORESYS */
#define RAND_DLL L"ADVAPI32.DLL"
#endif  /* _CORESYS */
        // advapi32.dll/cryptbase.dll is unloaded when the App exits.
        HMODULE hRandDll = LoadLibraryExW(RAND_DLL, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
#ifndef _CORESYS
        if (!hRandDll && GetLastError() == ERROR_INVALID_PARAMETER)
        {
            // LOAD_LIBRARY_SEARCH_SYSTEM32 is not supported on this platfrom,
            // try one more time using default options
            hRandDll = LoadLibraryExW(RAND_DLL, NULL, 0);
        }
#endif  /* _CORESYS */
        if (!hRandDll)
        {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), EINVAL);
        }

        pfnRtlGenRandom = ( PGENRANDOM ) GetProcAddress( hRandDll, _TO_STR( RtlGenRandom ) );
        if ( pfnRtlGenRandom == NULL )
        {
            _VALIDATE_RETURN_ERRCODE(("rand_s is not available on this platform", 0), _get_errno_from_oserr(GetLastError()));
        }
        encoded = (PGENRANDOM) EncodePointer(pfnRtlGenRandom);
        enull = EncodePointer(NULL);
#ifdef _M_IX86
        if ( (void*)(LONG_PTR)InterlockedExchange(
                ( LONG* )&g_pfnRtlGenRandom,
                ( LONG )( LONG_PTR )encoded)
            != enull )
#else  /* _M_IX86 */
        if ( InterlockedExchangePointer(
                ( void** )&g_pfnRtlGenRandom,
                ( void* )encoded)
            != enull )
#endif  /* _M_IX86 */
        {
            /* A different thread has already loaded advapi32.dll/cryptbase.dll. */
            FreeLibrary( hRandDll );
        }
    }

    if ( !(*pfnRtlGenRandom)( _RandomValue, ( ULONG )sizeof( unsigned int ) ) )
    {
        errno = ENOMEM;
        return errno;
    }
    return 0;
}