/* crypto/rand/rand_win.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */
/* ====================================================================
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#define OPENSSL_FIPSAPI

#include "cryptlib.h"
#include <openssl/rand.h>
#include "rand_lcl.h"

#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
#include <windows.h>
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
#endif
#include <wincrypt.h>
#include <tlhelp32.h>

/* Limit the time spent walking through the heap, processes, threads and modules to
   a maximum of 1000 miliseconds each, unless CryptoGenRandom failed */
#define MAXDELAY 1000

/* Intel hardware RNG CSP -- available from
 * http://developer.intel.com/design/security/rng/redist_license.htm
 */
#define PROV_INTEL_SEC 22
#define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"

static void readtimer(void);
static void readscreen(void);

/* It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined
   when WINVER is 0x0500 and up, which currently only happens on Win2000.
   Unfortunately, those are typedefs, so they're a little bit difficult to
   detect properly.  On the other hand, the macro CURSOR_SHOWING is defined
   within the same conditional, so it can be use to detect the absence of said
   typedefs. */

#ifndef CURSOR_SHOWING
/*
 * Information about the global cursor.
 */
typedef struct tagCURSORINFO
{
    DWORD   cbSize;
    DWORD   flags;
    HCURSOR hCursor;
    POINT   ptScreenPos;
} CURSORINFO, *PCURSORINFO, *LPCURSORINFO;

#define CURSOR_SHOWING     0x00000001
#endif /* CURSOR_SHOWING */

#if !defined(OPENSSL_SYS_WINCE)
typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTW)(HCRYPTPROV *, LPCWSTR, LPCWSTR,
				    DWORD, DWORD);
typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *);
typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV, DWORD);

typedef HWND (WINAPI *GETFOREGROUNDWINDOW)(VOID);
typedef BOOL (WINAPI *GETCURSORINFO)(PCURSORINFO);
typedef DWORD (WINAPI *GETQUEUESTATUS)(UINT);

typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, size_t);
typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
typedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32);
typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);

#include <lmcons.h>
#include <lmstats.h>
#if 1 /* The NET API is Unicode only.  It requires the use of the UNICODE
       * macro.  When UNICODE is defined LPTSTR becomes LPWSTR.  LMSTR was
       * was added to the Platform SDK to allow the NET API to be used in
       * non-Unicode applications provided that Unicode strings were still
       * used for input.  LMSTR is defined as LPWSTR.
       */
typedef NET_API_STATUS (NET_API_FUNCTION * NETSTATGET)
        (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE*);
typedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE);
#endif /* 1 */
#endif /* !OPENSSL_SYS_WINCE */

int RAND_poll(void)
{
	MEMORYSTATUS m;
	HCRYPTPROV hProvider = 0;
	DWORD w;
	int good = 0;

	/* Determine the OS version we are on so we can turn off things 
	 * that do not work properly.
	 */
        OSVERSIONINFO osverinfo ;
        osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
        GetVersionEx( &osverinfo ) ;

#if defined(OPENSSL_SYS_WINCE)
# if defined(_WIN32_WCE) && _WIN32_WCE>=300
/* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
 * in commonly available implementations prior 300... */
	{
	BYTE buf[64];
	/* poll the CryptoAPI PRNG */
	/* The CryptoAPI returns sizeof(buf) bytes of randomness */
	if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
				CRYPT_VERIFYCONTEXT))
		{
		if (CryptGenRandom(hProvider, sizeof(buf), buf))
			RAND_add(buf, sizeof(buf), sizeof(buf));
		CryptReleaseContext(hProvider, 0); 
		}
	}
# endif
#else	/* OPENSSL_SYS_WINCE */
	/*
	 * None of below libraries are present on Windows CE, which is
	 * why we #ifndef the whole section. This also excuses us from
	 * handling the GetProcAddress issue. The trouble is that in
	 * real Win32 API GetProcAddress is available in ANSI flavor
	 * only. In WinCE on the other hand GetProcAddress is a macro
	 * most commonly defined as GetProcAddressW, which accepts
	 * Unicode argument. If we were to call GetProcAddress under
	 * WinCE, I'd recommend to either redefine GetProcAddress as
	 * GetProcAddressA (there seem to be one in common CE spec) or
	 * implement own shim routine, which would accept ANSI argument
	 * and expand it to Unicode.
	 */
	{
	/* load functions dynamically - not available on all systems */
	HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
	HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
	HMODULE user = NULL;
	HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
	CRYPTACQUIRECONTEXTW acquire = NULL;
	CRYPTGENRANDOM gen = NULL;
	CRYPTRELEASECONTEXT release = NULL;
	NETSTATGET netstatget = NULL;
	NETFREE netfree = NULL;
	BYTE buf[64];

	if (netapi)
		{
		netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet");
		netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree");
		}

	if (netstatget && netfree)
		{
		LPBYTE outbuf;
		/* NetStatisticsGet() is a Unicode only function
 		 * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0
		 * contains 17 fields.  We treat each field as a source of
		 * one byte of entropy.
                 */

		if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0)
			{
			RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45);
			netfree(outbuf);
			}
		if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0)
			{
			RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
			netfree(outbuf);
			}
		}

	if (netapi)
		FreeLibrary(netapi);

        /* It appears like this can cause an exception deep within ADVAPI32.DLL
         * at random times on Windows 2000.  Reported by Jeffrey Altman.  
         * Only use it on NT.
	 */
	/* Wolfgang Marczy <WMarczy@topcall.co.at> reports that
	 * the RegQueryValueEx call below can hang on NT4.0 (SP6).
	 * So we don't use this at all for now. */
#if 0
        if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
		osverinfo.dwMajorVersion < 5)
		{
		/* Read Performance Statistics from NT/2000 registry
		 * The size of the performance data can vary from call
		 * to call so we must guess the size of the buffer to use
		 * and increase its size if we get an ERROR_MORE_DATA
		 * return instead of ERROR_SUCCESS.
		 */
		LONG   rc=ERROR_MORE_DATA;
		char * buf=NULL;
		DWORD bufsz=0;
		DWORD length;

		while (rc == ERROR_MORE_DATA)
			{
			buf = realloc(buf,bufsz+8192);
			if (!buf)
				break;
			bufsz += 8192;

			length = bufsz;
			rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, TEXT("Global"),
				NULL, NULL, buf, &length);
			}
		if (rc == ERROR_SUCCESS)
			{
                        /* For entropy count assume only least significant
			 * byte of each DWORD is random.
			 */
			RAND_add(&length, sizeof(length), 0);
			RAND_add(buf, length, length / 4.0);

			/* Close the Registry Key to allow Windows to cleanup/close
			 * the open handle
			 * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened
			 *       when the RegQueryValueEx above is done.  However, if
			 *       it is not explicitly closed, it can cause disk
			 *       partition manipulation problems.
			 */
			RegCloseKey(HKEY_PERFORMANCE_DATA);
			}
		if (buf)
			free(buf);
		}
#endif

	if (advapi)
		{
		/*
		 * If it's available, then it's available in both ANSI
		 * and UNICODE flavors even in Win9x, documentation says.
		 * We favor Unicode...
		 */
		acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
			"CryptAcquireContextW");
		gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
			"CryptGenRandom");
		release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
			"CryptReleaseContext");
		}

	if (acquire && gen && release)
		{
		/* poll the CryptoAPI PRNG */
                /* The CryptoAPI returns sizeof(buf) bytes of randomness */
		if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL,
			CRYPT_VERIFYCONTEXT))
			{
			if (gen(hProvider, sizeof(buf), buf) != 0)
				{
				RAND_add(buf, sizeof(buf), 0);
				good = 1;
#if 0
				printf("randomness from PROV_RSA_FULL\n");
#endif
				}
			release(hProvider, 0); 
			}
		
		/* poll the Pentium PRG with CryptoAPI */
		if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
			{
			if (gen(hProvider, sizeof(buf), buf) != 0)
				{
				RAND_add(buf, sizeof(buf), sizeof(buf));
				good = 1;
#if 0
				printf("randomness from PROV_INTEL_SEC\n");
#endif
				}
			release(hProvider, 0);
			}
		}

        if (advapi)
		FreeLibrary(advapi);

	if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
	     !OPENSSL_isservice()) &&
	    (user = LoadLibrary(TEXT("USER32.DLL"))))
		{
		GETCURSORINFO cursor;
		GETFOREGROUNDWINDOW win;
		GETQUEUESTATUS queue;

		win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
		cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
		queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");

		if (win)
			{
			/* window handle */
			HWND h = win();
			RAND_add(&h, sizeof(h), 0);
			}
		if (cursor)
			{
			/* unfortunately, its not safe to call GetCursorInfo()
			 * on NT4 even though it exists in SP3 (or SP6) and
			 * higher.
			 */
			if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
				osverinfo.dwMajorVersion < 5)
				cursor = 0;
			}
		if (cursor)
			{
			/* cursor position */
                        /* assume 2 bytes of entropy */
			CURSORINFO ci;
			ci.cbSize = sizeof(CURSORINFO);
			if (cursor(&ci))
				RAND_add(&ci, ci.cbSize, 2);
			}

		if (queue)
			{
			/* message queue status */
                        /* assume 1 byte of entropy */
			w = queue(QS_ALLEVENTS);
			RAND_add(&w, sizeof(w), 1);
			}

		FreeLibrary(user);
		}

	/* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
	 * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
	 * (Win 9x and 2000 only, not available on NT)
	 *
	 * This seeding method was proposed in Peter Gutmann, Software
	 * Generation of Practically Strong Random Numbers,
	 * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
	 * revised version at http://www.cryptoengines.com/~peter/06_random.pdf
	 * (The assignment of entropy estimates below is arbitrary, but based
	 * on Peter's analysis the full poll appears to be safe. Additional
	 * interactive seeding is encouraged.)
	 */

	if (kernel)
		{
		CREATETOOLHELP32SNAPSHOT snap;
		CLOSETOOLHELP32SNAPSHOT close_snap;
		HANDLE handle;

		HEAP32FIRST heap_first;
		HEAP32NEXT heap_next;
		HEAP32LIST heaplist_first, heaplist_next;
		PROCESS32 process_first, process_next;
		THREAD32 thread_first, thread_next;
		MODULE32 module_first, module_next;

		HEAPLIST32 hlist;
		HEAPENTRY32 hentry;
		PROCESSENTRY32 p;
		THREADENTRY32 t;
		MODULEENTRY32 m;
		DWORD starttime = 0;

		snap = (CREATETOOLHELP32SNAPSHOT)
			GetProcAddress(kernel, "CreateToolhelp32Snapshot");
		close_snap = (CLOSETOOLHELP32SNAPSHOT)
			GetProcAddress(kernel, "CloseToolhelp32Snapshot");
		heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
		heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
		heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
		heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
		process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
		process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
		thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
		thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
		module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
		module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");

		if (snap && heap_first && heap_next && heaplist_first &&
			heaplist_next && process_first && process_next &&
			thread_first && thread_next && module_first &&
			module_next && (handle = snap(TH32CS_SNAPALL,0))
			!= INVALID_HANDLE_VALUE)
			{
			/* heap list and heap walking */
                        /* HEAPLIST32 contains 3 fields that will change with
                         * each entry.  Consider each field a source of 1 byte
                         * of entropy.
                         * HEAPENTRY32 contains 5 fields that will change with 
                         * each entry.  Consider each field a source of 1 byte
                         * of entropy.
                         */
			ZeroMemory(&hlist, sizeof(HEAPLIST32));
			hlist.dwSize = sizeof(HEAPLIST32);		
			if (good) starttime = GetTickCount();
#ifdef _MSC_VER
			if (heaplist_first(handle, &hlist))
				{
				/*
				   following discussion on dev ML, exception on WinCE (or other Win
				   platform) is theoretically of unknown origin; prevent infinite
				   loop here when this theoretical case occurs; otherwise cope with
				   the expected (MSDN documented) exception-throwing behaviour of
				   Heap32Next() on WinCE.

				   based on patch in original message by Tanguy Fautré (2009/03/02)
			           Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
			     */
				int ex_cnt_limit = 42; 
				do
					{
					RAND_add(&hlist, hlist.dwSize, 3);
					__try
						{
						ZeroMemory(&hentry, sizeof(HEAPENTRY32));
					hentry.dwSize = sizeof(HEAPENTRY32);
					if (heap_first(&hentry,
						hlist.th32ProcessID,
						hlist.th32HeapID))
						{
						int entrycnt = 80;
						do
							RAND_add(&hentry,
								hentry.dwSize, 5);
						while (heap_next(&hentry)
						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
							&& --entrycnt > 0);
						}
						}
					__except (EXCEPTION_EXECUTE_HANDLER)
						{
							/* ignore access violations when walking the heap list */
							ex_cnt_limit--;
						}
					} while (heaplist_next(handle, &hlist) 
						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
						&& ex_cnt_limit > 0);
				}

#else
			if (heaplist_first(handle, &hlist))
				{
				do
					{
					RAND_add(&hlist, hlist.dwSize, 3);
					hentry.dwSize = sizeof(HEAPENTRY32);
					if (heap_first(&hentry,
						hlist.th32ProcessID,
						hlist.th32HeapID))
						{
						int entrycnt = 80;
						do
							RAND_add(&hentry,
								hentry.dwSize, 5);
						while (heap_next(&hentry)
							&& --entrycnt > 0);
						}
					} while (heaplist_next(handle, &hlist) 
						&& (!good || (GetTickCount()-starttime)<MAXDELAY));
				}
#endif

			/* process walking */
                        /* PROCESSENTRY32 contains 9 fields that will change
                         * with each entry.  Consider each field a source of
                         * 1 byte of entropy.
                         */
			p.dwSize = sizeof(PROCESSENTRY32);
		
			if (good) starttime = GetTickCount();
			if (process_first(handle, &p))
				do
					RAND_add(&p, p.dwSize, 9);
				while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));

			/* thread walking */
                        /* THREADENTRY32 contains 6 fields that will change
                         * with each entry.  Consider each field a source of
                         * 1 byte of entropy.
                         */
			t.dwSize = sizeof(THREADENTRY32);
			if (good) starttime = GetTickCount();
			if (thread_first(handle, &t))
				do
					RAND_add(&t, t.dwSize, 6);
				while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));

			/* module walking */
                        /* MODULEENTRY32 contains 9 fields that will change
                         * with each entry.  Consider each field a source of
                         * 1 byte of entropy.
                         */
			m.dwSize = sizeof(MODULEENTRY32);
			if (good) starttime = GetTickCount();
			if (module_first(handle, &m))
				do
					RAND_add(&m, m.dwSize, 9);
				while (module_next(handle, &m)
					       	&& (!good || (GetTickCount()-starttime)<MAXDELAY));
			if (close_snap)
				close_snap(handle);
			else
				CloseHandle(handle);

			}

		FreeLibrary(kernel);
		}
	}
#endif /* !OPENSSL_SYS_WINCE */

	/* timer data */
	readtimer();
	
	/* memory usage statistics */
	GlobalMemoryStatus(&m);
	RAND_add(&m, sizeof(m), 1);

	/* process ID */
	w = GetCurrentProcessId();
	RAND_add(&w, sizeof(w), 1);

#if 0
	printf("Exiting RAND_poll\n");
#endif

	return(1);
}

int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
        {
        double add_entropy=0;

        switch (iMsg)
                {
        case WM_KEYDOWN:
                        {
                        static WPARAM key;
                        if (key != wParam)
                                add_entropy = 0.05;
                        key = wParam;
                        }
                        break;
	case WM_MOUSEMOVE:
                        {
                        static int lastx,lasty,lastdx,lastdy;
                        int x,y,dx,dy;

                        x=LOWORD(lParam);
                        y=HIWORD(lParam);
                        dx=lastx-x;
                        dy=lasty-y;
                        if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0)
                                add_entropy=.2;
                        lastx=x, lasty=y;
                        lastdx=dx, lastdy=dy;
                        }
		break;
		}

	readtimer();
        RAND_add(&iMsg, sizeof(iMsg), add_entropy);
	RAND_add(&wParam, sizeof(wParam), 0);
	RAND_add(&lParam, sizeof(lParam), 0);
 
	return (RAND_status());
	}


void RAND_screen(void) /* function available for backward compatibility */
{
	RAND_poll();
	readscreen();
}


/* feed timing information to the PRNG */
static void readtimer(void)
{
	DWORD w;
	LARGE_INTEGER l;
	static int have_perfc = 1;
#if defined(_MSC_VER) && defined(_M_X86)
	static int have_tsc = 1;
	DWORD cyclecount;

	if (have_tsc) {
	  __try {
	    __asm {
	      _emit 0x0f
	      _emit 0x31
	      mov cyclecount, eax
	      }
	    RAND_add(&cyclecount, sizeof(cyclecount), 1);
	  } __except(EXCEPTION_EXECUTE_HANDLER) {
	    have_tsc = 0;
	  }
	}
#else
# define have_tsc 0
#endif

	if (have_perfc) {
	  if (QueryPerformanceCounter(&l) == 0)
	    have_perfc = 0;
	  else
	    RAND_add(&l, sizeof(l), 0);
	}

	if (!have_tsc && !have_perfc) {
	  w = GetTickCount();
	  RAND_add(&w, sizeof(w), 0);
	}
}

/* feed screen contents to PRNG */
/*****************************************************************************
 *
 * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
 *
 * Code adapted from
 * <URL:http://support.microsoft.com/default.aspx?scid=kb;[LN];97193>;
 * the original copyright message is:
 *
 *   (C) Copyright Microsoft Corp. 1993.  All rights reserved.
 *
 *   You have a royalty-free right to use, modify, reproduce and
 *   distribute the Sample Files (and/or any modified version) in
 *   any way you find useful, provided that you agree that
 *   Microsoft has no warranty obligations or liability for any
 *   Sample Application Files which are modified.
 */

static void readscreen(void)
{
#if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
  HDC		hScrDC;		/* screen DC */
  HDC		hMemDC;		/* memory DC */
  HBITMAP	hBitmap;	/* handle for our bitmap */
  HBITMAP	hOldBitmap;	/* handle for previous bitmap */
  BITMAP	bm;		/* bitmap properties */
  unsigned int	size;		/* size of bitmap */
  char		*bmbits;	/* contents of bitmap */
  int		w;		/* screen width */
  int		h;		/* screen height */
  int		y;		/* y-coordinate of screen lines to grab */
  int		n = 16;		/* number of screen lines to grab at a time */

  if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
    return;

  /* Create a screen DC and a memory DC compatible to screen DC */
  hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  hMemDC = CreateCompatibleDC(hScrDC);

  /* Get screen resolution */
  w = GetDeviceCaps(hScrDC, HORZRES);
  h = GetDeviceCaps(hScrDC, VERTRES);

  /* Create a bitmap compatible with the screen DC */
  hBitmap = CreateCompatibleBitmap(hScrDC, w, n);

  /* Select new bitmap into memory DC */
  hOldBitmap = SelectObject(hMemDC, hBitmap);

  /* Get bitmap properties */
  GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
  size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;

  bmbits = OPENSSL_malloc(size);
  if (bmbits) {
    /* Now go through the whole screen, repeatedly grabbing n lines */
    for (y = 0; y < h-n; y += n)
    	{
	unsigned char md[MD_DIGEST_LENGTH];

	/* Bitblt screen DC to memory DC */
	BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);

	/* Copy bitmap bits from memory DC to bmbits */
	GetBitmapBits(hBitmap, size, bmbits);

	/* Get the hash of the bitmap */
	MD(bmbits,size,md);

	/* Seed the random generator with the hash value */
	RAND_add(md, MD_DIGEST_LENGTH, 0);
	}

    OPENSSL_free(bmbits);
  }

  /* Select old bitmap back into memory DC */
  hBitmap = SelectObject(hMemDC, hOldBitmap);

  /* Clean up */
  DeleteObject(hBitmap);
  DeleteDC(hMemDC);
  DeleteDC(hScrDC);
#endif /* !OPENSSL_SYS_WINCE */
}

#endif
