Jeffrey Altman points out that GetQueueStatus() crashes on NT.
[openssl.git] / crypto / rand / rand_win.c
index 1f8ee6e758fad70223b5e531bf65d07aff5bc354..5dc186f78d8116a35f526126ae9db5d645a7cdd8 100644 (file)
 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 */
+
 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *, LPCTSTR, LPCTSTR,
                                    DWORD, DWORD);
 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *);
@@ -220,11 +242,9 @@ int RAND_poll(void)
                {
                GETCURSORINFO cursor;
                GETFOREGROUNDWINDOW win;
-               GETQUEUESTATUS queue;
 
                win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
                cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
-               queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");
 
                if (win)
                {
@@ -236,15 +256,10 @@ int RAND_poll(void)
                if (cursor)
                        {
                        /* cursor position */
-                       cursor(buf);
-                       RAND_add(buf, sizeof(buf), 0);
-                       }
-
-               if (queue)
-                       {
-                       /* message queue status */
-                       w = queue(QS_ALLEVENTS);
-                       RAND_add(&w, sizeof(w), 0);
+                        PCURSORINFO p = (PCURSORINFO) buf;
+                        p->cbSize = sizeof(CURSORINFO);
+                       if (cursor(p))
+                            RAND_add(p+sizeof(p->cbSize), p->cbSize-sizeof(p->cbSize), 0);
                        }
                }
 
@@ -254,7 +269,8 @@ int RAND_poll(void)
         *
         * This seeding method was proposed in Peter Gutmann, Software
         * Generation of Practically Strong Random Numbers,
-        * http://www.somewhere.nzhttp://www.cs.auckland.ac.nz/~pgut001/pubs/random2.pdf
+        * 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.)
@@ -307,10 +323,14 @@ int RAND_poll(void)
                                        if (heap_first(&hentry,
                                                hlist.th32ProcessID,
                                                hlist.th32HeapID))
+                                               {
+                                               int entrycnt = 50;
                                                do
                                                        RAND_add(&hentry,
                                                                hentry.dwSize, 0);
-                                               while (heap_next(&hentry));
+                                               while (heap_next(&hentry)
+                                                       && --entrycnt > 0);
+                                               }
                                        } while (heaplist_next(handle,
                                                &hlist));