/* 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).
 *
 */

#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)
							&& --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())
    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
