--- rand_win.c.orig	Wed Mar 09 18:48:55 2005
+++ rand_win.c	Wed Mar 09 18:47:23 2005
@@ -163,9 +163,19 @@
 
 typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
 typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
+
+/* Heap walking was found too slow on the Sharepoint 2003 server, there
+   were 1200 loops with HEAPENTRY run (with the maximum 80 per HEAPLIST
+   already), which took 15 seconds there. For 10 processes, 500 threads
+   and 10 modules there is still 3376 bytes of entropy without the heap
+   walking, if all calls to netapi32, advapi32, user32 and kernel32
+   succeed, which can be considered always on win2k or higher. */
+#if 0
 typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, DWORD);
 typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
 typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
+#endif
+
 typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
 typedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32);
 typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);
@@ -427,15 +437,19 @@
 		CLOSETOOLHELP32SNAPSHOT close_snap;
 		HANDLE handle;
 
+#if 0 /* Heap walking was too slow, see the comments higher. */
 		HEAP32FIRST heap_first;
 		HEAP32NEXT heap_next;
 		HEAP32LIST heaplist_first, heaplist_next;
+#endif
 		PROCESS32 process_first, process_next;
 		THREAD32 thread_first, thread_next;
 		MODULE32 module_first, module_next;
 
+#if 0 /* Heap walking was too slow, see the comments higher. */
 		HEAPLIST32 hlist;
 		HEAPENTRY32 hentry;
+#endif
 		PROCESSENTRY32 p;
 		THREADENTRY32 t;
 		MODULEENTRY32 m;
@@ -444,10 +458,12 @@
 			GetProcAddress(kernel, "CreateToolhelp32Snapshot");
 		close_snap = (CLOSETOOLHELP32SNAPSHOT)
 			GetProcAddress(kernel, "CloseToolhelp32Snapshot");
+#if 0 /* Heap walking was too slow, see the comments higher. */
 		heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
 		heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
 		heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
 		heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
+#endif
 		process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
 		process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
 		thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
@@ -455,12 +471,17 @@
 		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 &&
+		if (snap &&
+#if 0 /* Heap walking was too slow, see the comments higher. */
+		            heap_first && heap_next && heaplist_first &&
+			heaplist_next &&
+#endif
+			                 process_first && process_next &&
 			thread_first && thread_next && module_first &&
 			module_next && (handle = snap(TH32CS_SNAPALL,0))
 			!= INVALID_HANDLE_VALUE)
 			{
+#if 0 /* Heap walking was too slow, see the comments higher. */
 			/* heap list and heap walking */
                         /* HEAPLIST32 contains 3 fields that will change with
                          * each entry.  Consider each field a source of 1 byte
@@ -488,7 +509,15 @@
 						}
 					} while (heaplist_next(handle,
 						&hlist));
-			
+#endif
+
+/* Process, thread and module  walking was found a little slow on the
+   Sharepoint 2003 server, but only if there were too many kernel objects
+   (more than 256 or 512). It is unusual, however the constraint to 256/512
+   solves the problem enough. The slowness here is incomparable with the
+   heap walking, which was found slow also for small numbers of heap lists
+   and heap entries. */
+
 			/* process walking */
                         /* PROCESSENTRY32 contains 9 fields that will change
                          * with each entry.  Consider each field a source of
@@ -496,9 +525,12 @@
                          */
 			p.dwSize = sizeof(PROCESSENTRY32);
 			if (process_first(handle, &p))
+				{
+				int entrycnt = 256;
 				do
 					RAND_add(&p, p.dwSize, 9);
-				while (process_next(handle, &p));
+				while (--entrycnt > 0 && process_next(handle, &p));
+				}
 
 			/* thread walking */
                         /* THREADENTRY32 contains 6 fields that will change
@@ -507,9 +539,12 @@
                          */
 			t.dwSize = sizeof(THREADENTRY32);
 			if (thread_first(handle, &t))
+				{
+				int entrycnt = 512;
 				do
 					RAND_add(&t, t.dwSize, 6);
-				while (thread_next(handle, &t));
+				while (--entrycnt > 0 && thread_next(handle, &t));
+				}
 
 			/* module walking */
                         /* MODULEENTRY32 contains 9 fields that will change
@@ -518,9 +553,12 @@
                          */
 			m.dwSize = sizeof(MODULEENTRY32);
 			if (module_first(handle, &m))
+				{
+				int entrycnt = 256;
 				do
 					RAND_add(&m, m.dwSize, 9);
-				while (module_next(handle, &m));
+				while (--entrycnt > 0 && module_next(handle, &m));
+				}
 			if (close_snap)
 				close_snap(handle);
 			else
