Fix warning.
[openssl.git] / crypto / rand / rand_win.c
index 692a13eac594d363bc2601fa1a0a95ab4aba12b7..07ab4eb8dfea5c219aaf88bc05656a7b7b9e3341 100644 (file)
  *
  */
 
+#define OPENSSL_FIPSAPI
+
 #include "cryptlib.h"
 #include <openssl/rand.h>
 #include "rand_lcl.h"
@@ -168,7 +170,7 @@ 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 *HEAP32FIRST)(LPHEAPENTRY32, DWORD, size_t);
 typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
 typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
 typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
@@ -463,7 +465,7 @@ int RAND_poll(void)
                PROCESSENTRY32 p;
                THREADENTRY32 t;
                MODULEENTRY32 m;
-               DWORD stoptime = 0;
+               DWORD starttime = 0;
 
                snap = (CREATETOOLHELP32SNAPSHOT)
                        GetProcAddress(kernel, "CreateToolhelp32Snapshot");
@@ -494,9 +496,56 @@ int RAND_poll(void)
                          * each entry.  Consider each field a source of 1 byte
                          * of entropy.
                          */
+                       ZeroMemory(&hlist, sizeof(HEAPLIST32));
                        hlist.dwSize = sizeof(HEAPLIST32);              
-                       if (good) stoptime = GetTickCount() + MAXDELAY;
+                       if (good) starttime = GetTickCount();
+#ifdef _MSC_VER
+                       if (heaplist_first(handle, &hlist))
+                               {
+                               /*
+                                  following discussion on dev ML, exception on WinCE (or other Win
+                                  platform) is theoretically of unknown origin; prevent infinite
+                                  loop here when this theoretical case occurs; otherwise cope with
+                                  the expected (MSDN documented) exception-throwing behaviour of
+                                  Heap32Next() on WinCE.
+
+                                  based on patch in original message by Tanguy Fautré (2009/03/02)
+                                  Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
+                            */
+                               int ex_cnt_limit = 42; 
+                               do
+                                       {
+                                       RAND_add(&hlist, hlist.dwSize, 3);
+                                       __try
+                                               {
+                                               ZeroMemory(&hentry, sizeof(HEAPENTRY32));
+                                       hentry.dwSize = sizeof(HEAPENTRY32);
+                                       if (heap_first(&hentry,
+                                               hlist.th32ProcessID,
+                                               hlist.th32HeapID))
+                                               {
+                                               int entrycnt = 80;
+                                               do
+                                                       RAND_add(&hentry,
+                                                               hentry.dwSize, 5);
+                                               while (heap_next(&hentry)
+                                               && (!good || (GetTickCount()-starttime)<MAXDELAY)
+                                                       && --entrycnt > 0);
+                                               }
+                                               }
+                                       __except (EXCEPTION_EXECUTE_HANDLER)
+                                               {
+                                                       /* ignore access violations when walking the heap list */
+                                                       ex_cnt_limit--;
+                                               }
+                                       } while (heaplist_next(handle, &hlist) 
+                                               && (!good || (GetTickCount()-starttime)<MAXDELAY)
+                                               && ex_cnt_limit > 0);
+                               }
+
+#else
                        if (heaplist_first(handle, &hlist))
+                               {
                                do
                                        {
                                        RAND_add(&hlist, hlist.dwSize, 3);
@@ -512,8 +561,10 @@ int RAND_poll(void)
                                                while (heap_next(&hentry)
                                                        && --entrycnt > 0);
                                                }
-                                       } while (heaplist_next(handle,
-                                               &hlist) && GetTickCount() < stoptime);
+                                       } while (heaplist_next(handle, &hlist) 
+                                               && (!good || (GetTickCount()-starttime)<MAXDELAY));
+                               }
+#endif
 
                        /* process walking */
                         /* PROCESSENTRY32 contains 9 fields that will change
@@ -522,11 +573,11 @@ int RAND_poll(void)
                          */
                        p.dwSize = sizeof(PROCESSENTRY32);
                
-                       if (good) stoptime = GetTickCount() + MAXDELAY;
+                       if (good) starttime = GetTickCount();
                        if (process_first(handle, &p))
                                do
                                        RAND_add(&p, p.dwSize, 9);
-                               while (process_next(handle, &p) && GetTickCount() < stoptime);
+                               while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
 
                        /* thread walking */
                         /* THREADENTRY32 contains 6 fields that will change
@@ -534,11 +585,11 @@ int RAND_poll(void)
                          * 1 byte of entropy.
                          */
                        t.dwSize = sizeof(THREADENTRY32);
-                       if (good) stoptime = GetTickCount() + MAXDELAY;
+                       if (good) starttime = GetTickCount();
                        if (thread_first(handle, &t))
                                do
                                        RAND_add(&t, t.dwSize, 6);
-                               while (thread_next(handle, &t) && GetTickCount() < stoptime);
+                               while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
 
                        /* module walking */
                         /* MODULEENTRY32 contains 9 fields that will change
@@ -546,12 +597,12 @@ int RAND_poll(void)
                          * 1 byte of entropy.
                          */
                        m.dwSize = sizeof(MODULEENTRY32);
-                       if (good) stoptime = GetTickCount() + MAXDELAY;
+                       if (good) starttime = GetTickCount();
                        if (module_first(handle, &m))
                                do
                                        RAND_add(&m, m.dwSize, 9);
                                while (module_next(handle, &m)
-                                               && (GetTickCount() < stoptime));
+                                               && (!good || (GetTickCount()-starttime)<MAXDELAY));
                        if (close_snap)
                                close_snap(handle);
                        else
@@ -701,7 +752,7 @@ static void readscreen(void)
   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())
+  if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
     return;
 
   /* Create a screen DC and a memory DC compatible to screen DC */