1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/rand/rand_win.c */
2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * All rights reserved.
4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This package is an SSL implementation written
6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * by Eric Young (eay@cryptsoft.com).
7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The implementation was written so as to conform with Netscapes SSL.
8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This library is free for commercial and non-commercial use as long as
10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the following conditions are aheared to.  The following conditions
11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA,
12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * included with this distribution is covered by the same copyright terms
14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in
17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the code are not to be removed.
18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * If this package is used in a product, Eric Young should be given attribution
19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as the author of the parts of the library used.
20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This can be in the form of a textual message at program startup or
21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in documentation (online or textual) provided with the package.
22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the copyright
27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in the
30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    documentation and/or other materials provided with the distribution.
31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this software
32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    must display the following acknowledgement:
33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes cryptographic software written by
34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *     Eric Young (eay@cryptsoft.com)"
35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    The word 'cryptographic' can be left out if the rouines from the library
36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    being used are not cryptographic related :-).
37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from
38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the apps directory (application code) you must include an acknowledgement:
39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SUCH DAMAGE.
52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The licence and distribution terms for any publically available version or
54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * derivative of this code cannot be changed.  i.e. this code cannot simply be
55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * copied and put under another distribution licence
56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * [including the GNU Public Licence.]
57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ====================================================================
59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright
66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in
70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the documentation and/or other materials provided with the
71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    distribution.
72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this
74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    software must display the following acknowledgment:
75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    endorse or promote products derived from this software without
80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    prior written permission. For written permission, please contact
81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    openssl-core@openssl.org.
82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL"
84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    nor may "OpenSSL" appear in their names without prior written
85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    permission of the OpenSSL Project.
86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following
88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    acknowledgment:
89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE.
104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ====================================================================
105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young
107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com).  This product includes software written by Tim
108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com).
109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h"
113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/rand.h>
114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "rand_lcl.h"
115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <windows.h>
118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef _WIN32_WINNT
119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# define _WIN32_WINNT 0x0400
120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <wincrypt.h>
122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <tlhelp32.h>
123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Limit the time spent walking through the heap, processes, threads and modules to
125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org   a maximum of 1000 miliseconds each, unless CryptoGenRandom failed */
126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define MAXDELAY 1000
127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Intel hardware RNG CSP -- available from
129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * http://developer.intel.com/design/security/rng/redist_license.htm
130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define PROV_INTEL_SEC 22
132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void readtimer(void);
135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void readscreen(void);
136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined
138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org   when WINVER is 0x0500 and up, which currently only happens on Win2000.
139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org   Unfortunately, those are typedefs, so they're a little bit difficult to
140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org   detect properly.  On the other hand, the macro CURSOR_SHOWING is defined
141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org   within the same conditional, so it can be use to detect the absence of said
142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org   typedefs. */
143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef CURSOR_SHOWING
145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/*
146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Information about the global cursor.
147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef struct tagCURSORINFO
149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    DWORD   cbSize;
151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    DWORD   flags;
152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    HCURSOR hCursor;
153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    POINT   ptScreenPos;
154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org} CURSORINFO, *PCURSORINFO, *LPCURSORINFO;
155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#define CURSOR_SHOWING     0x00000001
157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif /* CURSOR_SHOWING */
158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if !defined(OPENSSL_SYS_WINCE)
160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *CRYPTACQUIRECONTEXTW)(HCRYPTPROV *, LPCWSTR, LPCWSTR,
161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				    DWORD, DWORD);
162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *);
163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV, DWORD);
164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef HWND (WINAPI *GETFOREGROUNDWINDOW)(VOID);
166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *GETCURSORINFO)(PCURSORINFO);
167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef DWORD (WINAPI *GETQUEUESTATUS)(UINT);
168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, size_t);
172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32);
176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);
177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <lmcons.h>
179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <lmstats.h>
180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 1 /* The NET API is Unicode only.  It requires the use of the UNICODE
181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org       * macro.  When UNICODE is defined LPTSTR becomes LPWSTR.  LMSTR was
182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org       * was added to the Platform SDK to allow the NET API to be used in
183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org       * non-Unicode applications provided that Unicode strings were still
184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org       * used for input.  LMSTR is defined as LPWSTR.
185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org       */
186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef NET_API_STATUS (NET_API_FUNCTION * NETSTATGET)
187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE*);
188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgtypedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE);
189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif /* 1 */
190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif /* !OPENSSL_SYS_WINCE */
191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint RAND_poll(void)
193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	MEMORYSTATUS m;
195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	HCRYPTPROV hProvider = 0;
196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	DWORD w;
197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int good = 0;
198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Determine the OS version we are on so we can turn off things
200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * that do not work properly.
201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        OSVERSIONINFO osverinfo ;
203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        GetVersionEx( &osverinfo ) ;
205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(OPENSSL_SYS_WINCE)
207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# if defined(_WIN32_WCE) && _WIN32_WCE>=300
208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in commonly available implementations prior 300... */
210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	BYTE buf[64];
212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* poll the CryptoAPI PRNG */
213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* The CryptoAPI returns sizeof(buf) bytes of randomness */
214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				CRYPT_VERIFYCONTEXT))
216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (CryptGenRandom(hProvider, sizeof(buf), buf))
218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(buf, sizeof(buf), sizeof(buf));
219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		CryptReleaseContext(hProvider, 0);
220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# endif
223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else	/* OPENSSL_SYS_WINCE */
224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/*
225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * None of below libraries are present on Windows CE, which is
226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * why we #ifndef the whole section. This also excuses us from
227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * handling the GetProcAddress issue. The trouble is that in
228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * real Win32 API GetProcAddress is available in ANSI flavor
229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * only. In WinCE on the other hand GetProcAddress is a macro
230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * most commonly defined as GetProcAddressW, which accepts
231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * Unicode argument. If we were to call GetProcAddress under
232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * WinCE, I'd recommend to either redefine GetProcAddress as
233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * GetProcAddressA (there seem to be one in common CE spec) or
234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * implement own shim routine, which would accept ANSI argument
235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * and expand it to Unicode.
236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* load functions dynamically - not available on all systems */
239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	HMODULE user = NULL;
242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	CRYPTACQUIRECONTEXTW acquire = NULL;
244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	CRYPTGENRANDOM gen = NULL;
245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	CRYPTRELEASECONTEXT release = NULL;
246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	NETSTATGET netstatget = NULL;
247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	NETFREE netfree = NULL;
248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	BYTE buf[64];
249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (netapi)
251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet");
253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree");
254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (netstatget && netfree)
257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		LPBYTE outbuf;
259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* NetStatisticsGet() is a Unicode only function
260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 		 * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0
261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * contains 17 fields.  We treat each field as a source of
262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * one byte of entropy.
263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                 */
264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0)
266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45);
268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			netfree(outbuf);
269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0)
271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			netfree(outbuf);
274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (netapi)
278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		FreeLibrary(netapi);
279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        /* It appears like this can cause an exception deep within ADVAPI32.DLL
281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org         * at random times on Windows 2000.  Reported by Jeffrey Altman.
282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org         * Only use it on NT.
283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Wolfgang Marczy <WMarczy@topcall.co.at> reports that
285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * the RegQueryValueEx call below can hang on NT4.0 (SP6).
286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * So we don't use this at all for now. */
287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0
288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		osverinfo.dwMajorVersion < 5)
290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Read Performance Statistics from NT/2000 registry
292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * The size of the performance data can vary from call
293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * to call so we must guess the size of the buffer to use
294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * and increase its size if we get an ERROR_MORE_DATA
295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * return instead of ERROR_SUCCESS.
296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 */
297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		LONG   rc=ERROR_MORE_DATA;
298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		char * buf=NULL;
299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		DWORD bufsz=0;
300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		DWORD length;
301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		while (rc == ERROR_MORE_DATA)
303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			buf = realloc(buf,bufsz+8192);
305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!buf)
306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				break;
307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			bufsz += 8192;
308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			length = bufsz;
310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, TEXT("Global"),
311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				NULL, NULL, buf, &length);
312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (rc == ERROR_SUCCESS)
314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* For entropy count assume only least significant
316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * byte of each DWORD is random.
317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 */
318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(&length, sizeof(length), 0);
319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(buf, length, length / 4.0);
320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* Close the Registry Key to allow Windows to cleanup/close
322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * the open handle
323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened
324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 *       when the RegQueryValueEx above is done.  However, if
325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 *       it is not explicitly closed, it can cause disk
326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 *       partition manipulation problems.
327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 */
328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RegCloseKey(HKEY_PERFORMANCE_DATA);
329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (buf)
331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			free(buf);
332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (advapi)
336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/*
338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * If it's available, then it's available in both ANSI
339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * and UNICODE flavors even in Win9x, documentation says.
340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * We favor Unicode...
341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 */
342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			"CryptAcquireContextW");
344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
345c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			"CryptGenRandom");
346c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
347c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			"CryptReleaseContext");
348c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (acquire && gen && release)
351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* poll the CryptoAPI PRNG */
353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                /* The CryptoAPI returns sizeof(buf) bytes of randomness */
354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL,
355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			CRYPT_VERIFYCONTEXT))
356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (gen(hProvider, sizeof(buf), buf) != 0)
358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				RAND_add(buf, sizeof(buf), 0);
360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				good = 1;
361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0
362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				printf("randomness from PROV_RSA_FULL\n");
363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			release(hProvider, 0);
366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* poll the Pentium PRG with CryptoAPI */
369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (gen(hProvider, sizeof(buf), buf) != 0)
372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				RAND_add(buf, sizeof(buf), sizeof(buf));
374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				good = 1;
375c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0
376c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				printf("randomness from PROV_INTEL_SEC\n");
377c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
378c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
379c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			release(hProvider, 0);
380c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
381c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
382c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
383c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        if (advapi)
384c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		FreeLibrary(advapi);
385c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
386c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
387c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	     !OPENSSL_isservice()) &&
388c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    (user = LoadLibrary(TEXT("USER32.DLL"))))
389c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
390c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		GETCURSORINFO cursor;
391c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		GETFOREGROUNDWINDOW win;
392c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		GETQUEUESTATUS queue;
393c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
394c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
395c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
396c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");
397c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
398c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (win)
399c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
400c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* window handle */
401c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			HWND h = win();
402c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(&h, sizeof(h), 0);
403c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
404c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (cursor)
405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
406c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* unfortunately, its not safe to call GetCursorInfo()
407c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * on NT4 even though it exists in SP3 (or SP6) and
408c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * higher.
409c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 */
410c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				osverinfo.dwMajorVersion < 5)
412c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				cursor = 0;
413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (cursor)
415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* cursor position */
417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* assume 2 bytes of entropy */
418c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			CURSORINFO ci;
419c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ci.cbSize = sizeof(CURSORINFO);
420c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (cursor(&ci))
421c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				RAND_add(&ci, ci.cbSize, 2);
422c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
423c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
424c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (queue)
425c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
426c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* message queue status */
427c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* assume 1 byte of entropy */
428c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			w = queue(QS_ALLEVENTS);
429c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			RAND_add(&w, sizeof(w), 1);
430c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
431c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
432c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		FreeLibrary(user);
433c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
434c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
435c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
436c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
437c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * (Win 9x and 2000 only, not available on NT)
438c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 *
439c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * This seeding method was proposed in Peter Gutmann, Software
440c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * Generation of Practically Strong Random Numbers,
441c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * revised version at http://www.cryptoengines.com/~peter/06_random.pdf
443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * (The assignment of entropy estimates below is arbitrary, but based
444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * on Peter's analysis the full poll appears to be safe. Additional
445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * interactive seeding is encouraged.)
446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
447c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
448c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (kernel)
449c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
450c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		CREATETOOLHELP32SNAPSHOT snap;
451c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		CLOSETOOLHELP32SNAPSHOT close_snap;
452c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		HANDLE handle;
453c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
454c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		HEAP32FIRST heap_first;
455c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		HEAP32NEXT heap_next;
456c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		HEAP32LIST heaplist_first, heaplist_next;
457c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		PROCESS32 process_first, process_next;
458c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		THREAD32 thread_first, thread_next;
459c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		MODULE32 module_first, module_next;
460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		HEAPLIST32 hlist;
462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		HEAPENTRY32 hentry;
463c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		PROCESSENTRY32 p;
464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		THREADENTRY32 t;
465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		MODULEENTRY32 m;
466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		DWORD starttime = 0;
467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
468c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		snap = (CREATETOOLHELP32SNAPSHOT)
469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			GetProcAddress(kernel, "CreateToolhelp32Snapshot");
470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		close_snap = (CLOSETOOLHELP32SNAPSHOT)
471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			GetProcAddress(kernel, "CloseToolhelp32Snapshot");
472c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
473c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");
482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (snap && heap_first && heap_next && heaplist_first &&
484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			heaplist_next && process_first && process_next &&
485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			thread_first && thread_next && module_first &&
486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			module_next && (handle = snap(TH32CS_SNAPALL,0))
487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			!= INVALID_HANDLE_VALUE)
488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* heap list and heap walking */
490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* HEAPLIST32 contains 3 fields that will change with
491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * each entry.  Consider each field a source of 1 byte
492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * of entropy.
493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * HEAPENTRY32 contains 5 fields that will change with
494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * each entry.  Consider each field a source of 1 byte
495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * of entropy.
496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         */
497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ZeroMemory(&hlist, sizeof(HEAPLIST32));
498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			hlist.dwSize = sizeof(HEAPLIST32);
499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (good) starttime = GetTickCount();
500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef _MSC_VER
501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (heaplist_first(handle, &hlist))
502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				/*
504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				   following discussion on dev ML, exception on WinCE (or other Win
505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				   platform) is theoretically of unknown origin; prevent infinite
506c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				   loop here when this theoretical case occurs; otherwise cope with
507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				   the expected (MSDN documented) exception-throwing behaviour of
508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				   Heap32Next() on WinCE.
509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				   based on patch in original message by Tanguy Fautré (2009/03/02)
511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			           Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			     */
513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				int ex_cnt_limit = 42;
514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				do
515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					{
516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					RAND_add(&hlist, hlist.dwSize, 3);
517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					__try
518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						{
519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						ZeroMemory(&hentry, sizeof(HEAPENTRY32));
520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					hentry.dwSize = sizeof(HEAPENTRY32);
521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					if (heap_first(&hentry,
522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						hlist.th32ProcessID,
523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						hlist.th32HeapID))
524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						{
525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						int entrycnt = 80;
526c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						do
527c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org							RAND_add(&hentry,
528c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org								hentry.dwSize, 5);
529c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						while (heap_next(&hentry)
530c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org							&& --entrycnt > 0);
532c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						}
533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						}
534c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					__except (EXCEPTION_EXECUTE_HANDLER)
535c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						{
536c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org							/* ignore access violations when walking the heap list */
537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org							ex_cnt_limit--;
538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						}
539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					} while (heaplist_next(handle, &hlist)
540c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						&& ex_cnt_limit > 0);
542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else
545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (heaplist_first(handle, &hlist))
546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				do
548c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					{
549c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					RAND_add(&hlist, hlist.dwSize, 3);
550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					hentry.dwSize = sizeof(HEAPENTRY32);
551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					if (heap_first(&hentry,
552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						hlist.th32ProcessID,
553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						hlist.th32HeapID))
554c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						{
555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						int entrycnt = 80;
556c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						do
557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org							RAND_add(&hentry,
558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org								hentry.dwSize, 5);
559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						while (heap_next(&hentry)
560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org							&& --entrycnt > 0);
561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						}
562c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					} while (heaplist_next(handle, &hlist)
563c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						&& (!good || (GetTickCount()-starttime)<MAXDELAY));
564c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* process walking */
568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* PROCESSENTRY32 contains 9 fields that will change
569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * with each entry.  Consider each field a source of
570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * 1 byte of entropy.
571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         */
572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			p.dwSize = sizeof(PROCESSENTRY32);
573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (good) starttime = GetTickCount();
575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (process_first(handle, &p))
576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				do
577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					RAND_add(&p, p.dwSize, 9);
578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* thread walking */
581c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* THREADENTRY32 contains 6 fields that will change
582c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * with each entry.  Consider each field a source of
583c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * 1 byte of entropy.
584c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         */
585c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			t.dwSize = sizeof(THREADENTRY32);
586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (good) starttime = GetTickCount();
587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (thread_first(handle, &t))
588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				do
589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					RAND_add(&t, t.dwSize, 6);
590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* module walking */
593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        /* MODULEENTRY32 contains 9 fields that will change
594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * with each entry.  Consider each field a source of
595c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         * 1 byte of entropy.
596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                         */
597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			m.dwSize = sizeof(MODULEENTRY32);
598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (good) starttime = GetTickCount();
599c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (module_first(handle, &m))
600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				do
601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					RAND_add(&m, m.dwSize, 9);
602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				while (module_next(handle, &m)
603c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					       	&& (!good || (GetTickCount()-starttime)<MAXDELAY));
604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (close_snap)
605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				close_snap(handle);
606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
607c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				CloseHandle(handle);
608c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
609c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
610c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
611c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		FreeLibrary(kernel);
612c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
613c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
614c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif /* !OPENSSL_SYS_WINCE */
615c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
616c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* timer data */
617c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	readtimer();
618c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
619c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* memory usage statistics */
620c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	GlobalMemoryStatus(&m);
621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	RAND_add(&m, sizeof(m), 1);
622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
623c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* process ID */
624c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	w = GetCurrentProcessId();
625c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	RAND_add(&w, sizeof(w), 1);
626c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0
628c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	printf("Exiting RAND_poll\n");
629c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
630c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
631c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return(1);
632c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
633c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
634c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
635c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        {
636c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        double add_entropy=0;
637c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
638c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        switch (iMsg)
639c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                {
640c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        case WM_KEYDOWN:
641c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        {
642c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        static WPARAM key;
643c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        if (key != wParam)
644c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                                add_entropy = 0.05;
645c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        key = wParam;
646c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        }
647c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        break;
648c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case WM_MOUSEMOVE:
649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        {
650c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        static int lastx,lasty,lastdx,lastdy;
651c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        int x,y,dx,dy;
652c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        x=LOWORD(lParam);
654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        y=HIWORD(lParam);
655c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        dx=lastx-x;
656c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        dy=lasty-y;
657c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0)
658c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                                add_entropy=.2;
659c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        lastx=x, lasty=y;
660c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        lastdx=dx, lastdy=dy;
661c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                        }
662c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		break;
663c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
664c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
665c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	readtimer();
666c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        RAND_add(&iMsg, sizeof(iMsg), add_entropy);
667c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	RAND_add(&wParam, sizeof(wParam), 0);
668c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	RAND_add(&lParam, sizeof(lParam), 0);
669c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
670c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return (RAND_status());
671c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
672c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
673c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
674c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid RAND_screen(void) /* function available for backward compatibility */
675c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
676c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	RAND_poll();
677c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	readscreen();
678c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
679c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
680c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* feed timing information to the PRNG */
682c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void readtimer(void)
683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
684c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	DWORD w;
685c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	LARGE_INTEGER l;
686c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	static int have_perfc = 1;
687c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if defined(_MSC_VER) && defined(_M_X86)
688c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	static int have_tsc = 1;
689c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	DWORD cyclecount;
690c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
691c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (have_tsc) {
692c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  __try {
693c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    __asm {
694c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	      _emit 0x0f
695c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	      _emit 0x31
696c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	      mov cyclecount, eax
697c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	      }
698c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    RAND_add(&cyclecount, sizeof(cyclecount), 1);
699c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  } __except(EXCEPTION_EXECUTE_HANDLER) {
700c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    have_tsc = 0;
701c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  }
702c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
703c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else
704c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org# define have_tsc 0
705c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
706c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
707c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (have_perfc) {
708c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  if (QueryPerformanceCounter(&l) == 0)
709c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    have_perfc = 0;
710c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  else
711c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    RAND_add(&l, sizeof(l), 0);
712c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
713c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
714c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!have_tsc && !have_perfc) {
715c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  w = GetTickCount();
716c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	  RAND_add(&w, sizeof(w), 0);
717c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
718c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
719c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
720c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* feed screen contents to PRNG */
721c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/*****************************************************************************
722c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
723c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
724c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
725c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Code adapted from
726c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * <URL:http://support.microsoft.com/default.aspx?scid=kb;[LN];97193>;
727c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the original copyright message is:
728c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
729c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *   (C) Copyright Microsoft Corp. 1993.  All rights reserved.
730c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
731c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *   You have a royalty-free right to use, modify, reproduce and
732c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *   distribute the Sample Files (and/or any modified version) in
733c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *   any way you find useful, provided that you agree that
734c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *   Microsoft has no warranty obligations or liability for any
735c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *   Sample Application Files which are modified.
736c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
737c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
738c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic void readscreen(void)
739c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
740c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
741c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  HDC		hScrDC;		/* screen DC */
742c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  HDC		hMemDC;		/* memory DC */
743c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  HBITMAP	hBitmap;	/* handle for our bitmap */
744c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  HBITMAP	hOldBitmap;	/* handle for previous bitmap */
745c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  BITMAP	bm;		/* bitmap properties */
746c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  unsigned int	size;		/* size of bitmap */
747c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  char		*bmbits;	/* contents of bitmap */
748c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  int		w;		/* screen width */
749c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  int		h;		/* screen height */
750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  int		y;		/* y-coordinate of screen lines to grab */
751c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  int		n = 16;		/* number of screen lines to grab at a time */
752c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
753c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    return;
755c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
756c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Create a screen DC and a memory DC compatible to screen DC */
757c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
758c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  hMemDC = CreateCompatibleDC(hScrDC);
759c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
760c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Get screen resolution */
761c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  w = GetDeviceCaps(hScrDC, HORZRES);
762c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  h = GetDeviceCaps(hScrDC, VERTRES);
763c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
764c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Create a bitmap compatible with the screen DC */
765c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
766c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
767c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Select new bitmap into memory DC */
768c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  hOldBitmap = SelectObject(hMemDC, hBitmap);
769c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
770c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Get bitmap properties */
771c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
772c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
774c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  bmbits = OPENSSL_malloc(size);
775c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  if (bmbits) {
776c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    /* Now go through the whole screen, repeatedly grabbing n lines */
777c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    for (y = 0; y < h-n; y += n)
778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    	{
779c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned char md[MD_DIGEST_LENGTH];
780c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
781c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Bitblt screen DC to memory DC */
782c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
783c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
784c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Copy bitmap bits from memory DC to bmbits */
785c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	GetBitmapBits(hBitmap, size, bmbits);
786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Get the hash of the bitmap */
788c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	MD(bmbits,size,md);
789c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
790c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Seed the random generator with the hash value */
791c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	RAND_add(md, MD_DIGEST_LENGTH, 0);
792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
793c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
794c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org    OPENSSL_free(bmbits);
795c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  }
796c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
797c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Select old bitmap back into memory DC */
798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  hBitmap = SelectObject(hMemDC, hOldBitmap);
799c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
800c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  /* Clean up */
801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  DeleteObject(hBitmap);
802c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  DeleteDC(hMemDC);
803c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org  DeleteDC(hScrDC);
804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif /* !OPENSSL_SYS_WINCE */
805c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
806c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
808