aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c')
-rw-r--r--[-rwxr-xr-x]linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c1380
1 files changed, 690 insertions, 690 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c
index cbd44e6..b8e2d62 100755..100644
--- a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c
+++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/rndw32.c
@@ -1,690 +1,690 @@
1/* rndw32.c - W32 entropy gatherer 1/* rndw32.c - W32 entropy gatherer
2 * Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc. 2 * Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3 * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999 3 * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
4 * 4 *
5 * This file is part of Libgcrypt. 5 * This file is part of Libgcrypt.
6 * 6 *
7 ************************************************************************* 7 *************************************************************************
8 * The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann. 8 * The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann.
9 * Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this 9 * Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this
10 * copyright notice: 10 * copyright notice:
11 * 11 *
12 * This module is part of the cryptlib continuously seeded pseudorandom 12 * This module is part of the cryptlib continuously seeded pseudorandom
13 * number generator. For usage conditions, see lib_rand.c 13 * number generator. For usage conditions, see lib_rand.c
14 * 14 *
15 * [Here is the notice from lib_rand.c, which is now called dev_sys.c] 15 * [Here is the notice from lib_rand.c, which is now called dev_sys.c]
16 * 16 *
17 * This module and the misc/rnd*.c modules represent the cryptlib 17 * This module and the misc/rnd*.c modules represent the cryptlib
18 * continuously seeded pseudorandom number generator (CSPRNG) as described in 18 * continuously seeded pseudorandom number generator (CSPRNG) as described in
19 * my 1998 Usenix Security Symposium paper "The generation of random numbers 19 * my 1998 Usenix Security Symposium paper "The generation of random numbers
20 * for cryptographic purposes". 20 * for cryptographic purposes".
21 * 21 *
22 * The CSPRNG code is copyright Peter Gutmann (and various others) 1996, 22 * The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
23 * 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG 23 * 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
24 * modules and use in source and binary forms, with or without modification, 24 * modules and use in source and binary forms, with or without modification,
25 * are permitted provided that the following conditions are met: 25 * are permitted provided that the following conditions are met:
26 * 26 *
27 * 1. Redistributions of source code must retain the above copyright notice 27 * 1. Redistributions of source code must retain the above copyright notice
28 * and this permission notice in its entirety. 28 * and this permission notice in its entirety.
29 * 29 *
30 * 2. Redistributions in binary form must reproduce the copyright notice in 30 * 2. Redistributions in binary form must reproduce the copyright notice in
31 * the documentation and/or other materials provided with the distribution. 31 * the documentation and/or other materials provided with the distribution.
32 * 32 *
33 * 3. A copy of any bugfixes or enhancements made must be provided to the 33 * 3. A copy of any bugfixes or enhancements made must be provided to the
34 * author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the 34 * author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
35 * baseline version of the code. 35 * baseline version of the code.
36 * 36 *
37 * ALTERNATIVELY, the code may be distributed under the terms of the GNU 37 * ALTERNATIVELY, the code may be distributed under the terms of the GNU
38 * General Public License, version 2 or any later version published by the 38 * General Public License, version 2 or any later version published by the
39 * Free Software Foundation, in which case the provisions of the GNU GPL are 39 * Free Software Foundation, in which case the provisions of the GNU GPL are
40 * required INSTEAD OF the above restrictions. 40 * required INSTEAD OF the above restrictions.
41 * 41 *
42 * Although not required under the terms of the GPL, it would still be nice if 42 * Although not required under the terms of the GPL, it would still be nice if
43 * you could make any changes available to the author to allow a consistent 43 * you could make any changes available to the author to allow a consistent
44 * code base to be maintained 44 * code base to be maintained
45 ************************************************************************* 45 *************************************************************************
46 */ 46 */
47 47
48#include <config.h> 48#include <config.h>
49#include <stdio.h> 49#include <stdio.h>
50#include <stdlib.h> 50#include <stdlib.h>
51#include <assert.h> 51#include <assert.h>
52#include <errno.h> 52#include <errno.h>
53#include <string.h> 53#include <string.h>
54 54
55#include <windows.h> 55#include <windows.h>
56 56
57 57
58#include "types.h" 58#include "types.h"
59#include "g10lib.h" 59#include "g10lib.h"
60#include "rand-internal.h" 60#include "rand-internal.h"
61 61
62 62
63static int debug_me; 63static int debug_me;
64 64
65/* 65/*
66 * Definitions which are missing from the current GNU Windows32Api 66 * Definitions which are missing from the current GNU Windows32Api
67 */ 67 */
68 68
69#ifndef TH32CS_SNAPHEAPLIST 69#ifndef TH32CS_SNAPHEAPLIST
70#define TH32CS_SNAPHEAPLIST 1 70#define TH32CS_SNAPHEAPLIST 1
71#define TH32CS_SNAPPROCESS 2 71#define TH32CS_SNAPPROCESS 2
72#define TH32CS_SNAPTHREAD 4 72#define TH32CS_SNAPTHREAD 4
73#define TH32CS_SNAPMODULE 8 73#define TH32CS_SNAPMODULE 8
74#define TH32CS_SNAPALL (1|2|4|8) 74#define TH32CS_SNAPALL (1|2|4|8)
75#define TH32CS_INHERIT 0x80000000 75#define TH32CS_INHERIT 0x80000000
76#endif /*TH32CS_SNAPHEAPLIST*/ 76#endif /*TH32CS_SNAPHEAPLIST*/
77 77
78#ifndef IOCTL_DISK_PERFORMANCE 78#ifndef IOCTL_DISK_PERFORMANCE
79#define IOCTL_DISK_PERFORMANCE 0x00070020 79#define IOCTL_DISK_PERFORMANCE 0x00070020
80#endif 80#endif
81#ifndef VER_PLATFORM_WIN32_WINDOWS 81#ifndef VER_PLATFORM_WIN32_WINDOWS
82#define VER_PLATFORM_WIN32_WINDOWS 1 82#define VER_PLATFORM_WIN32_WINDOWS 1
83#endif 83#endif
84 84
85/* This used to be (6*8+5*4+8*2), but Peter Gutmann figured a larger 85/* This used to be (6*8+5*4+8*2), but Peter Gutmann figured a larger
86 value in a newer release. So we use a far larger value. */ 86 value in a newer release. So we use a far larger value. */
87#define SIZEOF_DISK_PERFORMANCE_STRUCT 256 87#define SIZEOF_DISK_PERFORMANCE_STRUCT 256
88 88
89 89
90typedef struct { 90typedef struct {
91 DWORD dwSize; 91 DWORD dwSize;
92 DWORD th32ProcessID; 92 DWORD th32ProcessID;
93 DWORD th32HeapID; 93 DWORD th32HeapID;
94 DWORD dwFlags; 94 DWORD dwFlags;
95} HEAPLIST32; 95} HEAPLIST32;
96 96
97typedef struct { 97typedef struct {
98 DWORD dwSize; 98 DWORD dwSize;
99 HANDLE hHandle; 99 HANDLE hHandle;
100 DWORD dwAddress; 100 DWORD dwAddress;
101 DWORD dwBlockSize; 101 DWORD dwBlockSize;
102 DWORD dwFlags; 102 DWORD dwFlags;
103 DWORD dwLockCount; 103 DWORD dwLockCount;
104 DWORD dwResvd; 104 DWORD dwResvd;
105 DWORD th32ProcessID; 105 DWORD th32ProcessID;
106 DWORD th32HeapID; 106 DWORD th32HeapID;
107} HEAPENTRY32; 107} HEAPENTRY32;
108 108
109typedef struct { 109typedef struct {
110 DWORD dwSize; 110 DWORD dwSize;
111 DWORD cntUsage; 111 DWORD cntUsage;
112 DWORD th32ProcessID; 112 DWORD th32ProcessID;
113 DWORD th32DefaultHeapID; 113 DWORD th32DefaultHeapID;
114 DWORD th32ModuleID; 114 DWORD th32ModuleID;
115 DWORD cntThreads; 115 DWORD cntThreads;
116 DWORD th32ParentProcessID; 116 DWORD th32ParentProcessID;
117 LONG pcPriClassBase; 117 LONG pcPriClassBase;
118 DWORD dwFlags; 118 DWORD dwFlags;
119 char szExeFile[260]; 119 char szExeFile[260];
120} PROCESSENTRY32; 120} PROCESSENTRY32;
121 121
122typedef struct { 122typedef struct {
123 DWORD dwSize; 123 DWORD dwSize;
124 DWORD cntUsage; 124 DWORD cntUsage;
125 DWORD th32ThreadID; 125 DWORD th32ThreadID;
126 DWORD th32OwnerProcessID; 126 DWORD th32OwnerProcessID;
127 LONG tpBasePri; 127 LONG tpBasePri;
128 LONG tpDeltaPri; 128 LONG tpDeltaPri;
129 DWORD dwFlags; 129 DWORD dwFlags;
130} THREADENTRY32; 130} THREADENTRY32;
131 131
132typedef struct { 132typedef struct {
133 DWORD dwSize; 133 DWORD dwSize;
134 DWORD th32ModuleID; 134 DWORD th32ModuleID;
135 DWORD th32ProcessID; 135 DWORD th32ProcessID;
136 DWORD GlblcntUsage; 136 DWORD GlblcntUsage;
137 DWORD ProccntUsage; 137 DWORD ProccntUsage;
138 BYTE *modBaseAddr; 138 BYTE *modBaseAddr;
139 DWORD modBaseSize; 139 DWORD modBaseSize;
140 HMODULE hModule; 140 HMODULE hModule;
141 char szModule[256]; 141 char szModule[256];
142 char szExePath[260]; 142 char szExePath[260];
143} MODULEENTRY32; 143} MODULEENTRY32;
144 144
145 145
146 146
147/* Type definitions for function pointers to call Toolhelp32 functions 147/* Type definitions for function pointers to call Toolhelp32 functions
148 * used with the windows95 gatherer */ 148 * used with the windows95 gatherer */
149typedef BOOL (WINAPI * MODULEWALK) (HANDLE hSnapshot, MODULEENTRY32 *lpme); 149typedef BOOL (WINAPI * MODULEWALK) (HANDLE hSnapshot, MODULEENTRY32 *lpme);
150typedef BOOL (WINAPI * THREADWALK) (HANDLE hSnapshot, THREADENTRY32 *lpte); 150typedef BOOL (WINAPI * THREADWALK) (HANDLE hSnapshot, THREADENTRY32 *lpte);
151typedef BOOL (WINAPI * PROCESSWALK) (HANDLE hSnapshot, PROCESSENTRY32 *lppe); 151typedef BOOL (WINAPI * PROCESSWALK) (HANDLE hSnapshot, PROCESSENTRY32 *lppe);
152typedef BOOL (WINAPI * HEAPLISTWALK) (HANDLE hSnapshot, HEAPLIST32 *lphl); 152typedef BOOL (WINAPI * HEAPLISTWALK) (HANDLE hSnapshot, HEAPLIST32 *lphl);
153typedef BOOL (WINAPI * HEAPFIRST) (HEAPENTRY32 *lphe, DWORD th32ProcessID, 153typedef BOOL (WINAPI * HEAPFIRST) (HEAPENTRY32 *lphe, DWORD th32ProcessID,
154 DWORD th32HeapID); 154 DWORD th32HeapID);
155typedef BOOL (WINAPI * HEAPNEXT) (HEAPENTRY32 *lphe); 155typedef BOOL (WINAPI * HEAPNEXT) (HEAPENTRY32 *lphe);
156typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD dwFlags, DWORD th32ProcessID); 156typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD dwFlags, DWORD th32ProcessID);
157 157
158/* Type definitions for function pointers to call NetAPI32 functions */ 158/* Type definitions for function pointers to call NetAPI32 functions */
159typedef DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService, 159typedef DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
160 DWORD dwLevel, DWORD dwOptions, 160 DWORD dwLevel, DWORD dwOptions,
161 LPBYTE * lpBuffer); 161 LPBYTE * lpBuffer);
162typedef DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer); 162typedef DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
163typedef DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer); 163typedef DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
164 164
165 165
166/* When we query the performance counters, we allocate an initial buffer and 166/* When we query the performance counters, we allocate an initial buffer and
167 * then reallocate it as required until RegQueryValueEx() stops returning 167 * then reallocate it as required until RegQueryValueEx() stops returning
168 * ERROR_MORE_DATA. The following values define the initial buffer size and 168 * ERROR_MORE_DATA. The following values define the initial buffer size and
169 * step size by which the buffer is increased 169 * step size by which the buffer is increased
170 */ 170 */
171#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */ 171#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */
172#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */ 172#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */
173 173
174 174
175static void 175static void
176slow_gatherer_windows95( void (*add)(const void*, size_t, int), int requester ) 176slow_gatherer_windows95( void (*add)(const void*, size_t, int), int requester )
177{ 177{
178 static CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL; 178 static CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
179 static MODULEWALK pModule32First = NULL; 179 static MODULEWALK pModule32First = NULL;
180 static MODULEWALK pModule32Next = NULL; 180 static MODULEWALK pModule32Next = NULL;
181 static PROCESSWALK pProcess32First = NULL; 181 static PROCESSWALK pProcess32First = NULL;
182 static PROCESSWALK pProcess32Next = NULL; 182 static PROCESSWALK pProcess32Next = NULL;
183 static THREADWALK pThread32First = NULL; 183 static THREADWALK pThread32First = NULL;
184 static THREADWALK pThread32Next = NULL; 184 static THREADWALK pThread32Next = NULL;
185 static HEAPLISTWALK pHeap32ListFirst = NULL; 185 static HEAPLISTWALK pHeap32ListFirst = NULL;
186 static HEAPLISTWALK pHeap32ListNext = NULL; 186 static HEAPLISTWALK pHeap32ListNext = NULL;
187 static HEAPFIRST pHeap32First = NULL; 187 static HEAPFIRST pHeap32First = NULL;
188 static HEAPNEXT pHeap32Next = NULL; 188 static HEAPNEXT pHeap32Next = NULL;
189 HANDLE hSnapshot; 189 HANDLE hSnapshot;
190 190
191 191
192 /* initialize the Toolhelp32 function pointers */ 192 /* initialize the Toolhelp32 function pointers */
193 if ( !pCreateToolhelp32Snapshot ) { 193 if ( !pCreateToolhelp32Snapshot ) {
194 HANDLE hKernel; 194 HANDLE hKernel;
195 195
196 if ( debug_me ) 196 if ( debug_me )
197 log_debug ("rndw32#slow_gatherer_95: init toolkit\n" ); 197 log_debug ("rndw32#slow_gatherer_95: init toolkit\n" );
198 198
199 /* Obtain the module handle of the kernel to retrieve the addresses 199 /* Obtain the module handle of the kernel to retrieve the addresses
200 * of the Toolhelp32 functions */ 200 * of the Toolhelp32 functions */
201 if ( ( !(hKernel = GetModuleHandle ("KERNEL32.DLL"))) ) { 201 if ( ( !(hKernel = GetModuleHandle ("KERNEL32.DLL"))) ) {
202 log_fatal ( "rndw32: can't get module handle\n" ); 202 log_fatal ( "rndw32: can't get module handle\n" );
203 } 203 }
204 204
205 /* Now get pointers to the functions */ 205 /* Now get pointers to the functions */
206 pCreateToolhelp32Snapshot = (CREATESNAPSHOT) GetProcAddress (hKernel, 206 pCreateToolhelp32Snapshot = (CREATESNAPSHOT) GetProcAddress (hKernel,
207 "CreateToolhelp32Snapshot"); 207 "CreateToolhelp32Snapshot");
208 pModule32First = (MODULEWALK) GetProcAddress (hKernel, "Module32First"); 208 pModule32First = (MODULEWALK) GetProcAddress (hKernel, "Module32First");
209 pModule32Next = (MODULEWALK) GetProcAddress (hKernel, "Module32Next"); 209 pModule32Next = (MODULEWALK) GetProcAddress (hKernel, "Module32Next");
210 pProcess32First = (PROCESSWALK) GetProcAddress (hKernel, 210 pProcess32First = (PROCESSWALK) GetProcAddress (hKernel,
211 "Process32First"); 211 "Process32First");
212 pProcess32Next = (PROCESSWALK) GetProcAddress (hKernel, 212 pProcess32Next = (PROCESSWALK) GetProcAddress (hKernel,
213 "Process32Next"); 213 "Process32Next");
214 pThread32First = (THREADWALK) GetProcAddress (hKernel, "Thread32First"); 214 pThread32First = (THREADWALK) GetProcAddress (hKernel, "Thread32First");
215 pThread32Next = (THREADWALK) GetProcAddress (hKernel, "Thread32Next"); 215 pThread32Next = (THREADWALK) GetProcAddress (hKernel, "Thread32Next");
216 pHeap32ListFirst = (HEAPLISTWALK) GetProcAddress (hKernel, 216 pHeap32ListFirst = (HEAPLISTWALK) GetProcAddress (hKernel,
217 "Heap32ListFirst"); 217 "Heap32ListFirst");
218 pHeap32ListNext = (HEAPLISTWALK) GetProcAddress (hKernel, 218 pHeap32ListNext = (HEAPLISTWALK) GetProcAddress (hKernel,
219 "Heap32ListNext"); 219 "Heap32ListNext");
220 pHeap32First = (HEAPFIRST) GetProcAddress (hKernel, "Heap32First"); 220 pHeap32First = (HEAPFIRST) GetProcAddress (hKernel, "Heap32First");
221 pHeap32Next = (HEAPNEXT) GetProcAddress (hKernel, "Heap32Next"); 221 pHeap32Next = (HEAPNEXT) GetProcAddress (hKernel, "Heap32Next");
222 222
223 if ( !pCreateToolhelp32Snapshot 223 if ( !pCreateToolhelp32Snapshot
224 || !pModule32First || !pModule32Next 224 || !pModule32First || !pModule32Next
225 || !pProcess32First || !pProcess32Next 225 || !pProcess32First || !pProcess32Next
226 || !pThread32First || !pThread32Next 226 || !pThread32First || !pThread32Next
227 || !pHeap32ListFirst || !pHeap32ListNext 227 || !pHeap32ListFirst || !pHeap32ListNext
228 || !pHeap32First || !pHeap32Next ) { 228 || !pHeap32First || !pHeap32Next ) {
229 log_fatal ( "rndw32: failed to get a toolhelp function\n" ); 229 log_fatal ( "rndw32: failed to get a toolhelp function\n" );
230 } 230 }
231 } 231 }
232 232
233 /* Take a snapshot of everything we can get to which is currently 233 /* Take a snapshot of everything we can get to which is currently
234 * in the system */ 234 * in the system */
235 if ( !(hSnapshot = pCreateToolhelp32Snapshot (TH32CS_SNAPALL, 0)) ) { 235 if ( !(hSnapshot = pCreateToolhelp32Snapshot (TH32CS_SNAPALL, 0)) ) {
236 log_fatal ( "rndw32: failed to take a toolhelp snapshot\n" ); 236 log_fatal ( "rndw32: failed to take a toolhelp snapshot\n" );
237 } 237 }
238 238
239 /* Walk through the local heap */ 239 /* Walk through the local heap */
240 { HEAPLIST32 hl32; 240 { HEAPLIST32 hl32;
241 DWORD dwHeapsAdded = 0; 241 DWORD dwHeapsAdded = 0;
242 const DWORD maxHeapsToAdd = 500; 242 const DWORD maxHeapsToAdd = 500;
243 hl32.dwSize = sizeof (HEAPLIST32); 243 hl32.dwSize = sizeof (HEAPLIST32);
244 if (pHeap32ListFirst (hSnapshot, &hl32)) { 244 if (pHeap32ListFirst (hSnapshot, &hl32)) {
245 if ( debug_me ) 245 if ( debug_me )
246 log_debug ("rndw32#slow_gatherer_95: walk heap\n" ); 246 log_debug ("rndw32#slow_gatherer_95: walk heap\n" );
247 do { 247 do {
248 HEAPENTRY32 he32; 248 HEAPENTRY32 he32;
249 249
250 /* First add the information from the basic Heaplist32 struct */ 250 /* First add the information from the basic Heaplist32 struct */
251 (*add) ( &hl32, sizeof (hl32), requester ); 251 (*add) ( &hl32, sizeof (hl32), requester );
252 252
253 /* Now walk through the heap blocks getting information 253 /* Now walk through the heap blocks getting information
254 * on each of them */ 254 * on each of them */
255 he32.dwSize = sizeof (HEAPENTRY32); 255 he32.dwSize = sizeof (HEAPENTRY32);
256 if (pHeap32First (&he32, hl32.th32ProcessID, hl32.th32HeapID)){ 256 if (pHeap32First (&he32, hl32.th32ProcessID, hl32.th32HeapID)){
257 do { 257 do {
258 (*add) ( &he32, sizeof (he32), requester ); 258 (*add) ( &he32, sizeof (he32), requester );
259 if (++dwHeapsAdded == maxHeapsToAdd) { 259 if (++dwHeapsAdded == maxHeapsToAdd) {
260 goto doneheap; 260 goto doneheap;
261 } 261 }
262 } while (pHeap32Next (&he32)); 262 } while (pHeap32Next (&he32));
263 } 263 }
264 } while (pHeap32ListNext (hSnapshot, &hl32)); 264 } while (pHeap32ListNext (hSnapshot, &hl32));
265 } 265 }
266 } 266 }
267 267
268doneheap: 268doneheap:
269 269
270 /* Walk through all processes */ 270 /* Walk through all processes */
271 { PROCESSENTRY32 pe32; 271 { PROCESSENTRY32 pe32;
272 pe32.dwSize = sizeof (PROCESSENTRY32); 272 pe32.dwSize = sizeof (PROCESSENTRY32);
273 if (pProcess32First (hSnapshot, &pe32)) { 273 if (pProcess32First (hSnapshot, &pe32)) {
274 if ( debug_me ) 274 if ( debug_me )
275 log_debug ("rndw32#slow_gatherer_95: walk processes\n" ); 275 log_debug ("rndw32#slow_gatherer_95: walk processes\n" );
276 do { 276 do {
277 (*add) ( &pe32, sizeof (pe32), requester ); 277 (*add) ( &pe32, sizeof (pe32), requester );
278 } while (pProcess32Next (hSnapshot, &pe32)); 278 } while (pProcess32Next (hSnapshot, &pe32));
279 } 279 }
280 } 280 }
281 281
282 /* Walk through all threads */ 282 /* Walk through all threads */
283 { THREADENTRY32 te32; 283 { THREADENTRY32 te32;
284 te32.dwSize = sizeof (THREADENTRY32); 284 te32.dwSize = sizeof (THREADENTRY32);
285 if (pThread32First (hSnapshot, &te32)) { 285 if (pThread32First (hSnapshot, &te32)) {
286 if ( debug_me ) 286 if ( debug_me )
287 log_debug ("rndw32#slow_gatherer_95: walk threads\n" ); 287 log_debug ("rndw32#slow_gatherer_95: walk threads\n" );
288 do { 288 do {
289 (*add) ( &te32, sizeof (te32), requester ); 289 (*add) ( &te32, sizeof (te32), requester );
290 } while (pThread32Next (hSnapshot, &te32)); 290 } while (pThread32Next (hSnapshot, &te32));
291 } 291 }
292 } 292 }
293 293
294 /* Walk through all modules associated with the process */ 294 /* Walk through all modules associated with the process */
295 { MODULEENTRY32 me32; 295 { MODULEENTRY32 me32;
296 me32.dwSize = sizeof (MODULEENTRY32); 296 me32.dwSize = sizeof (MODULEENTRY32);
297 if (pModule32First (hSnapshot, &me32)) { 297 if (pModule32First (hSnapshot, &me32)) {
298 if ( debug_me ) 298 if ( debug_me )
299 log_debug ("rndw32#slow_gatherer_95: walk modules\n" ); 299 log_debug ("rndw32#slow_gatherer_95: walk modules\n" );
300 do { 300 do {
301 (*add) ( &me32, sizeof (me32), requester ); 301 (*add) ( &me32, sizeof (me32), requester );
302 } while (pModule32Next (hSnapshot, &me32)); 302 } while (pModule32Next (hSnapshot, &me32));
303 } 303 }
304 } 304 }
305 305
306 CloseHandle (hSnapshot); 306 CloseHandle (hSnapshot);
307} 307}
308 308
309 309
310 310
311static void 311static void
312slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester ) 312slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
313{ 313{
314 static int is_initialized = 0; 314 static int is_initialized = 0;
315 static NETSTATISTICSGET pNetStatisticsGet = NULL; 315 static NETSTATISTICSGET pNetStatisticsGet = NULL;
316 static NETAPIBUFFERSIZE pNetApiBufferSize = NULL; 316 static NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
317 static NETAPIBUFFERFREE pNetApiBufferFree = NULL; 317 static NETAPIBUFFERFREE pNetApiBufferFree = NULL;
318 static int is_workstation = 1; 318 static int is_workstation = 1;
319 319
320 static int cbPerfData = PERFORMANCE_BUFFER_SIZE; 320 static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
321 PERF_DATA_BLOCK *pPerfData; 321 PERF_DATA_BLOCK *pPerfData;
322 HANDLE hDevice, hNetAPI32 = NULL; 322 HANDLE hDevice, hNetAPI32 = NULL;
323 DWORD dwSize, status; 323 DWORD dwSize, status;
324 int nDrive; 324 int nDrive;
325 325
326 if ( !is_initialized ) { 326 if ( !is_initialized ) {
327 HKEY hKey; 327 HKEY hKey;
328 328
329 if ( debug_me ) 329 if ( debug_me )
330 log_debug ("rndw32#slow_gatherer_nt: init toolkit\n" ); 330 log_debug ("rndw32#slow_gatherer_nt: init toolkit\n" );
331 /* Find out whether this is an NT server or workstation if necessary */ 331 /* Find out whether this is an NT server or workstation if necessary */
332 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, 332 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
333 "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 333 "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
334 0, KEY_READ, &hKey) == ERROR_SUCCESS) { 334 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
335 BYTE szValue[32]; 335 BYTE szValue[32];
336 dwSize = sizeof (szValue); 336 dwSize = sizeof (szValue);
337 337
338 if ( debug_me ) 338 if ( debug_me )
339 log_debug ("rndw32#slow_gatherer_nt: check product options\n" ); 339 log_debug ("rndw32#slow_gatherer_nt: check product options\n" );
340 status = RegQueryValueEx (hKey, "ProductType", 0, NULL, 340 status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
341 szValue, &dwSize); 341 szValue, &dwSize);
342 if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) { 342 if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) {
343 /* Note: There are (at least) three cases for ProductType: 343 /* Note: There are (at least) three cases for ProductType:
344 * WinNT = NT Workstation, ServerNT = NT Server, LanmanNT = 344 * WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
345 * NT Server acting as a Domain Controller */ 345 * NT Server acting as a Domain Controller */
346 is_workstation = 0; 346 is_workstation = 0;
347 if ( debug_me ) 347 if ( debug_me )
348 log_debug ("rndw32: this is a NT server\n"); 348 log_debug ("rndw32: this is a NT server\n");
349 } 349 }
350 RegCloseKey (hKey); 350 RegCloseKey (hKey);
351 } 351 }
352 352
353 /* Initialize the NetAPI32 function pointers if necessary */ 353 /* Initialize the NetAPI32 function pointers if necessary */
354 if ( (hNetAPI32 = LoadLibrary ("NETAPI32.DLL")) ) { 354 if ( (hNetAPI32 = LoadLibrary ("NETAPI32.DLL")) ) {
355 if ( debug_me ) 355 if ( debug_me )
356 log_debug ("rndw32#slow_gatherer_nt: netapi32 loaded\n" ); 356 log_debug ("rndw32#slow_gatherer_nt: netapi32 loaded\n" );
357 pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32, 357 pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
358 "NetStatisticsGet"); 358 "NetStatisticsGet");
359 pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32, 359 pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
360 "NetApiBufferSize"); 360 "NetApiBufferSize");
361 pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32, 361 pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
362 "NetApiBufferFree"); 362 "NetApiBufferFree");
363 363
364 if ( !pNetStatisticsGet 364 if ( !pNetStatisticsGet
365 || !pNetApiBufferSize || !pNetApiBufferFree ) { 365 || !pNetApiBufferSize || !pNetApiBufferFree ) {
366 FreeLibrary (hNetAPI32); 366 FreeLibrary (hNetAPI32);
367 hNetAPI32 = NULL; 367 hNetAPI32 = NULL;
368 log_debug ("rndw32: No NETAPI found\n" ); 368 log_debug ("rndw32: No NETAPI found\n" );
369 } 369 }
370 } 370 }
371 371
372 is_initialized = 1; 372 is_initialized = 1;
373 } 373 }
374 374
375 /* Get network statistics. Note: Both NT Workstation and NT Server by 375 /* Get network statistics. Note: Both NT Workstation and NT Server by
376 * default will be running both the workstation and server services. The 376 * default will be running both the workstation and server services. The
377 * heuristic below is probably useful though on the assumption that the 377 * heuristic below is probably useful though on the assumption that the
378 * majority of the network traffic will be via the appropriate service. 378 * majority of the network traffic will be via the appropriate service.
379 * In any case the network statistics return almost no randomness */ 379 * In any case the network statistics return almost no randomness */
380 { LPBYTE lpBuffer; 380 { LPBYTE lpBuffer;
381 if (hNetAPI32 && !pNetStatisticsGet (NULL, 381 if (hNetAPI32 && !pNetStatisticsGet (NULL,
382 is_workstation ? L"LanmanWorkstation" : 382 is_workstation ? L"LanmanWorkstation" :
383 L"LanmanServer", 0, 0, &lpBuffer) ) { 383 L"LanmanServer", 0, 0, &lpBuffer) ) {
384 if ( debug_me ) 384 if ( debug_me )
385 log_debug ("rndw32#slow_gatherer_nt: get netstats\n" ); 385 log_debug ("rndw32#slow_gatherer_nt: get netstats\n" );
386 pNetApiBufferSize (lpBuffer, &dwSize); 386 pNetApiBufferSize (lpBuffer, &dwSize);
387 (*add) ( lpBuffer, dwSize,requester ); 387 (*add) ( lpBuffer, dwSize,requester );
388 pNetApiBufferFree (lpBuffer); 388 pNetApiBufferFree (lpBuffer);
389 } 389 }
390 } 390 }
391 391
392 /* Get disk I/O statistics for all the hard drives */ 392 /* Get disk I/O statistics for all the hard drives */
393 for (nDrive = 0;; nDrive++) { 393 for (nDrive = 0;; nDrive++) {
394 char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT]; 394 char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT];
395 char szDevice[50]; 395 char szDevice[50];
396 396
397 /* Check whether we can access this device */ 397 /* Check whether we can access this device */
398 sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive); 398 sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
399 hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 399 hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
400 NULL, OPEN_EXISTING, 0, NULL); 400 NULL, OPEN_EXISTING, 0, NULL);
401 if (hDevice == INVALID_HANDLE_VALUE) 401 if (hDevice == INVALID_HANDLE_VALUE)
402 break; 402 break;
403 403
404 /* Note: This only works if you have turned on the disk performance 404 /* Note: This only works if you have turned on the disk performance
405 * counters with 'diskperf -y'. These counters are off by default */ 405 * counters with 'diskperf -y'. These counters are off by default */
406 if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, 406 if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
407 &diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT, 407 &diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
408 &dwSize, NULL)) 408 &dwSize, NULL))
409 { 409 {
410 if ( debug_me ) 410 if ( debug_me )
411 log_debug ("rndw32#slow_gatherer_nt: iostats drive %d\n", 411 log_debug ("rndw32#slow_gatherer_nt: iostats drive %d\n",
412 nDrive ); 412 nDrive );
413 (*add) (diskPerformance, dwSize, requester ); 413 (*add) (diskPerformance, dwSize, requester );
414 } 414 }
415 else { 415 else {
416 log_info ("NOTE: you should run 'diskperf -y' " 416 log_info ("NOTE: you should run 'diskperf -y' "
417 "to enable the disk statistics\n"); 417 "to enable the disk statistics\n");
418 } 418 }
419 CloseHandle (hDevice); 419 CloseHandle (hDevice);
420 } 420 }
421 421
422#if 0 /* we don't need this in GnuPG */ 422#if 0 /* we don't need this in GnuPG */
423 /* Wait for any async keyset driver binding to complete. You may be 423 /* Wait for any async keyset driver binding to complete. You may be
424 * wondering what this call is doing here... the reason it's necessary is 424 * wondering what this call is doing here... the reason it's necessary is
425 * because RegQueryValueEx() will hang indefinitely if the async driver 425 * because RegQueryValueEx() will hang indefinitely if the async driver
426 * bind is in progress. The problem occurs in the dynamic loading and 426 * bind is in progress. The problem occurs in the dynamic loading and
427 * linking of driver DLL's, which work as follows: 427 * linking of driver DLL's, which work as follows:
428 * 428 *
429 * hDriver = LoadLibrary( DRIVERNAME ); 429 * hDriver = LoadLibrary( DRIVERNAME );
430 * pFunction1 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC1 ); 430 * pFunction1 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC1 );
431 * pFunction2 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC2 ); 431 * pFunction2 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC2 );
432 * 432 *
433 * If RegQueryValueEx() is called while the GetProcAddress()'s are in 433 * If RegQueryValueEx() is called while the GetProcAddress()'s are in
434 * progress, it will hang indefinitely. This is probably due to some 434 * progress, it will hang indefinitely. This is probably due to some
435 * synchronisation problem in the NT kernel where the GetProcAddress() 435 * synchronisation problem in the NT kernel where the GetProcAddress()
436 * calls affect something like a module reference count or function 436 * calls affect something like a module reference count or function
437 * reference count while RegQueryValueEx() is trying to take a snapshot 437 * reference count while RegQueryValueEx() is trying to take a snapshot
438 * of the statistics, which include the reference counts. Because of 438 * of the statistics, which include the reference counts. Because of
439 * this, we have to wait until any async driver bind has completed 439 * this, we have to wait until any async driver bind has completed
440 * before we can call RegQueryValueEx() */ 440 * before we can call RegQueryValueEx() */
441 waitSemaphore (SEMAPHORE_DRIVERBIND); 441 waitSemaphore (SEMAPHORE_DRIVERBIND);
442#endif 442#endif
443 443
444 /* Get information from the system performance counters. This can take 444 /* Get information from the system performance counters. This can take
445 * a few seconds to do. In some environments the call to 445 * a few seconds to do. In some environments the call to
446 * RegQueryValueEx() can produce an access violation at some random time 446 * RegQueryValueEx() can produce an access violation at some random time
447 * in the future, adding a short delay after the following code block 447 * in the future, adding a short delay after the following code block
448 * makes the problem go away. This problem is extremely difficult to 448 * makes the problem go away. This problem is extremely difficult to
449 * reproduce, I haven't been able to get it to occur despite running it 449 * reproduce, I haven't been able to get it to occur despite running it
450 * on a number of machines. The best explanation for the problem is that 450 * on a number of machines. The best explanation for the problem is that
451 * on the machine where it did occur, it was caused by an external driver 451 * on the machine where it did occur, it was caused by an external driver
452 * or other program which adds its own values under the 452 * or other program which adds its own values under the
453 * HKEY_PERFORMANCE_DATA key. The NT kernel calls the required external 453 * HKEY_PERFORMANCE_DATA key. The NT kernel calls the required external
454 * modules to map in the data, if there's a synchronisation problem the 454 * modules to map in the data, if there's a synchronisation problem the
455 * external module would write its data at an inappropriate moment, 455 * external module would write its data at an inappropriate moment,
456 * causing the access violation. A low-level memory checker indicated 456 * causing the access violation. A low-level memory checker indicated
457 * that ExpandEnvironmentStrings() in KERNEL32.DLL, called an 457 * that ExpandEnvironmentStrings() in KERNEL32.DLL, called an
458 * interminable number of calls down inside RegQueryValueEx(), was 458 * interminable number of calls down inside RegQueryValueEx(), was
459 * overwriting memory (it wrote twice the allocated size of a buffer to a 459 * overwriting memory (it wrote twice the allocated size of a buffer to a
460 * buffer allocated by the NT kernel). This may be what's causing the 460 * buffer allocated by the NT kernel). This may be what's causing the
461 * problem, but since it's in the kernel there isn't much which can be 461 * problem, but since it's in the kernel there isn't much which can be
462 * done. 462 * done.
463 * 463 *
464 * In addition to these problems the code in RegQueryValueEx() which 464 * In addition to these problems the code in RegQueryValueEx() which
465 * estimates the amount of memory required to return the performance 465 * estimates the amount of memory required to return the performance
466 * counter information isn't very accurate, since it always returns a 466 * counter information isn't very accurate, since it always returns a
467 * worst-case estimate which is usually nowhere near the actual amount 467 * worst-case estimate which is usually nowhere near the actual amount
468 * required. For example it may report that 128K of memory is required, 468 * required. For example it may report that 128K of memory is required,
469 * but only return 64K of data */ 469 * but only return 64K of data */
470 { pPerfData = gcry_xmalloc (cbPerfData); 470 { pPerfData = gcry_xmalloc (cbPerfData);
471 for (;;) { 471 for (;;) {
472 dwSize = cbPerfData; 472 dwSize = cbPerfData;
473 if ( debug_me ) 473 if ( debug_me )
474 log_debug ("rndw32#slow_gatherer_nt: get perf data\n" ); 474 log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
475 status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL, 475 status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
476 NULL, (LPBYTE) pPerfData, &dwSize); 476 NULL, (LPBYTE) pPerfData, &dwSize);
477 if (status == ERROR_SUCCESS) { 477 if (status == ERROR_SUCCESS) {
478 if (!memcmp (pPerfData->Signature, L"PERF", 8)) { 478 if (!memcmp (pPerfData->Signature, L"PERF", 8)) {
479 (*add) ( pPerfData, dwSize, requester ); 479 (*add) ( pPerfData, dwSize, requester );
480 } 480 }
481 else 481 else
482 log_debug ( "rndw32: no PERF signature\n"); 482 log_debug ( "rndw32: no PERF signature\n");
483 break; 483 break;
484 } 484 }
485 else if (status == ERROR_MORE_DATA) { 485 else if (status == ERROR_MORE_DATA) {
486 cbPerfData += PERFORMANCE_BUFFER_STEP; 486 cbPerfData += PERFORMANCE_BUFFER_STEP;
487 pPerfData = gcry_realloc (pPerfData, cbPerfData); 487 pPerfData = gcry_realloc (pPerfData, cbPerfData);
488 } 488 }
489 else { 489 else {
490 log_debug ( "rndw32: get performance data problem\n"); 490 log_debug ( "rndw32: get performance data problem\n");
491 break; 491 break;
492 } 492 }
493 } 493 }
494 gcry_free (pPerfData); 494 gcry_free (pPerfData);
495 } 495 }
496 /* Although this isn't documented in the Win32 API docs, it's necessary 496 /* Although this isn't documented in the Win32 API docs, it's necessary
497 to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's 497 to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
498 implicitly opened on the first call to RegQueryValueEx()). If this 498 implicitly opened on the first call to RegQueryValueEx()). If this
499 isn't done then any system components which provide performance data 499 isn't done then any system components which provide performance data
500 can't be removed or changed while the handle remains active */ 500 can't be removed or changed while the handle remains active */
501 RegCloseKey (HKEY_PERFORMANCE_DATA); 501 RegCloseKey (HKEY_PERFORMANCE_DATA);
502} 502}
503 503
504 504
505int 505int
506_gcry_rndw32_gather_random( void (*add)(const void*, size_t, int), 506_gcry_rndw32_gather_random( void (*add)(const void*, size_t, int),
507 int requester, 507 int requester,
508 size_t length, int level ) 508 size_t length, int level )
509{ 509{
510 static int is_initialized; 510 static int is_initialized;
511 static int is_windowsNT, has_toolhelp; 511 static int is_windowsNT, has_toolhelp;
512 512
513 513
514 if( !level ) 514 if( !level )
515 return 0; 515 return 0;
516 /* We don't differentiate between level 1 and 2 here because 516 /* We don't differentiate between level 1 and 2 here because
517 * there is no internal entropy pool as a scary resource. It may 517 * there is no internal entropy pool as a scary resource. It may
518 * all work slower, but because our entropy source will never 518 * all work slower, but because our entropy source will never
519 * block but deliver some not easy to measure entropy, we assume level 2 519 * block but deliver some not easy to measure entropy, we assume level 2
520 */ 520 */
521 521
522 522
523 if ( !is_initialized ) { 523 if ( !is_initialized ) {
524 OSVERSIONINFO osvi = { sizeof( osvi ) }; 524 OSVERSIONINFO osvi = { sizeof( osvi ) };
525 DWORD platform; 525 DWORD platform;
526 526
527 GetVersionEx( &osvi ); 527 GetVersionEx( &osvi );
528 platform = osvi.dwPlatformId; 528 platform = osvi.dwPlatformId;
529 is_windowsNT = platform == VER_PLATFORM_WIN32_NT; 529 is_windowsNT = platform == VER_PLATFORM_WIN32_NT;
530 has_toolhelp = (platform == VER_PLATFORM_WIN32_WINDOWS 530 has_toolhelp = (platform == VER_PLATFORM_WIN32_WINDOWS
531 || (is_windowsNT && osvi.dwMajorVersion >= 5)); 531 || (is_windowsNT && osvi.dwMajorVersion >= 5));
532 532
533 if ( platform == VER_PLATFORM_WIN32s ) { 533 if ( platform == VER_PLATFORM_WIN32s ) {
534 log_fatal("can't run on a W32s platform\n" ); 534 log_fatal("can't run on a W32s platform\n" );
535 } 535 }
536 is_initialized = 1; 536 is_initialized = 1;
537 if ( debug_me ) 537 if ( debug_me )
538 log_debug ("rndw32#gather_random: platform=%d\n", (int)platform ); 538 log_debug ("rndw32#gather_random: platform=%d\n", (int)platform );
539 } 539 }
540 540
541 541
542 if ( debug_me ) 542 if ( debug_me )
543 log_debug ("rndw32#gather_random: req=%d len=%u lvl=%d\n", 543 log_debug ("rndw32#gather_random: req=%d len=%u lvl=%d\n",
544 requester, (unsigned int)length, level ); 544 requester, (unsigned int)length, level );
545 545
546 if ( is_windowsNT ) { 546 if ( is_windowsNT ) {
547 slow_gatherer_windowsNT ( add, requester ); 547 slow_gatherer_windowsNT ( add, requester );
548 } 548 }
549 else if ( has_toolhelp ) { 549 else if ( has_toolhelp ) {
550 slow_gatherer_windows95 ( add, requester ); 550 slow_gatherer_windows95 ( add, requester );
551 } 551 }
552 552
553 553
554 return 0; 554 return 0;
555} 555}
556 556
557 557
558int 558int
559_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, int), 559_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, int),
560 int requester ) 560 int requester )
561{ 561{
562 static int addedFixedItems = 0; 562 static int addedFixedItems = 0;
563 563
564 if ( debug_me ) 564 if ( debug_me )
565 log_debug ("rndw32#gather_random_fast: req=%d\n", requester ); 565 log_debug ("rndw32#gather_random_fast: req=%d\n", requester );
566 566
567 /* Get various basic pieces of system information: Handle of active 567 /* Get various basic pieces of system information: Handle of active
568 * window, handle of window with mouse capture, handle of clipboard owner 568 * window, handle of window with mouse capture, handle of clipboard owner
569 * handle of start of clpboard viewer list, pseudohandle of current 569 * handle of start of clpboard viewer list, pseudohandle of current
570 * process, current process ID, pseudohandle of current thread, current 570 * process, current process ID, pseudohandle of current thread, current
571 * thread ID, handle of desktop window, handle of window with keyboard 571 * thread ID, handle of desktop window, handle of window with keyboard
572 * focus, whether system queue has any events, cursor position for last 572 * focus, whether system queue has any events, cursor position for last
573 * message, 1 ms time for last message, handle of window with clipboard 573 * message, 1 ms time for last message, handle of window with clipboard
574 * open, handle of process heap, handle of procs window station, types of 574 * open, handle of process heap, handle of procs window station, types of
575 * events in input queue, and milliseconds since Windows was started */ 575 * events in input queue, and milliseconds since Windows was started */
576 { byte buffer[20*sizeof(ulong)], *bufptr; 576 { byte buffer[20*sizeof(ulong)], *bufptr;
577 bufptr = buffer; 577 bufptr = buffer;
578#define ADD(f) do { ulong along = (ulong)(f); \ 578#define ADD(f) do { ulong along = (ulong)(f); \
579 memcpy (bufptr, &along, sizeof (along) ); \ 579 memcpy (bufptr, &along, sizeof (along) ); \
580 bufptr += sizeof (along); } while (0) 580 bufptr += sizeof (along); } while (0)
581 ADD ( GetActiveWindow ()); 581 ADD ( GetActiveWindow ());
582 ADD ( GetCapture ()); 582 ADD ( GetCapture ());
583 ADD ( GetClipboardOwner ()); 583 ADD ( GetClipboardOwner ());
584 ADD ( GetClipboardViewer ()); 584 ADD ( GetClipboardViewer ());
585 ADD ( GetCurrentProcess ()); 585 ADD ( GetCurrentProcess ());
586 ADD ( GetCurrentProcessId ()); 586 ADD ( GetCurrentProcessId ());
587 ADD ( GetCurrentThread ()); 587 ADD ( GetCurrentThread ());
588 ADD ( GetCurrentThreadId ()); 588 ADD ( GetCurrentThreadId ());
589 ADD ( GetDesktopWindow ()); 589 ADD ( GetDesktopWindow ());
590 ADD ( GetFocus ()); 590 ADD ( GetFocus ());
591 ADD ( GetInputState ()); 591 ADD ( GetInputState ());
592 ADD ( GetMessagePos ()); 592 ADD ( GetMessagePos ());
593 ADD ( GetMessageTime ()); 593 ADD ( GetMessageTime ());
594 ADD ( GetOpenClipboardWindow ()); 594 ADD ( GetOpenClipboardWindow ());
595 ADD ( GetProcessHeap ()); 595 ADD ( GetProcessHeap ());
596 ADD ( GetProcessWindowStation ()); 596 ADD ( GetProcessWindowStation ());
597 ADD ( GetQueueStatus (QS_ALLEVENTS)); 597 ADD ( GetQueueStatus (QS_ALLEVENTS));
598 ADD ( GetTickCount ()); 598 ADD ( GetTickCount ());
599 599
600 assert ( bufptr-buffer < sizeof (buffer) ); 600 assert ( bufptr-buffer < sizeof (buffer) );
601 (*add) ( buffer, bufptr-buffer, requester ); 601 (*add) ( buffer, bufptr-buffer, requester );
602#undef ADD 602#undef ADD
603 } 603 }
604 604
605 /* Get multiword system information: Current caret position, current 605 /* Get multiword system information: Current caret position, current
606 * mouse cursor position */ 606 * mouse cursor position */
607 { POINT point; 607 { POINT point;
608 GetCaretPos (&point); 608 GetCaretPos (&point);
609 (*add) ( &point, sizeof (point), requester ); 609 (*add) ( &point, sizeof (point), requester );
610 GetCursorPos (&point); 610 GetCursorPos (&point);
611 (*add) ( &point, sizeof (point), requester ); 611 (*add) ( &point, sizeof (point), requester );
612 } 612 }
613 613
614 /* Get percent of memory in use, bytes of physical memory, bytes of free 614 /* Get percent of memory in use, bytes of physical memory, bytes of free
615 * physical memory, bytes in paging file, free bytes in paging file, user 615 * physical memory, bytes in paging file, free bytes in paging file, user
616 * bytes of address space, and free user bytes */ 616 * bytes of address space, and free user bytes */
617 { MEMORYSTATUS memoryStatus; 617 { MEMORYSTATUS memoryStatus;
618 memoryStatus.dwLength = sizeof (MEMORYSTATUS); 618 memoryStatus.dwLength = sizeof (MEMORYSTATUS);
619 GlobalMemoryStatus (&memoryStatus); 619 GlobalMemoryStatus (&memoryStatus);
620 (*add) ( &memoryStatus, sizeof (memoryStatus), requester ); 620 (*add) ( &memoryStatus, sizeof (memoryStatus), requester );
621 } 621 }
622 622
623 /* Get thread and process creation time, exit time, time in kernel mode, 623 /* Get thread and process creation time, exit time, time in kernel mode,
624 and time in user mode in 100ns intervals */ 624 and time in user mode in 100ns intervals */
625 { HANDLE handle; 625 { HANDLE handle;
626 FILETIME creationTime, exitTime, kernelTime, userTime; 626 FILETIME creationTime, exitTime, kernelTime, userTime;
627 DWORD minimumWorkingSetSize, maximumWorkingSetSize; 627 DWORD minimumWorkingSetSize, maximumWorkingSetSize;
628 628
629 handle = GetCurrentThread (); 629 handle = GetCurrentThread ();
630 GetThreadTimes (handle, &creationTime, &exitTime, 630 GetThreadTimes (handle, &creationTime, &exitTime,
631 &kernelTime, &userTime); 631 &kernelTime, &userTime);
632 (*add) ( &creationTime, sizeof (creationTime), requester ); 632 (*add) ( &creationTime, sizeof (creationTime), requester );
633 (*add) ( &exitTime, sizeof (exitTime), requester ); 633 (*add) ( &exitTime, sizeof (exitTime), requester );
634 (*add) ( &kernelTime, sizeof (kernelTime), requester ); 634 (*add) ( &kernelTime, sizeof (kernelTime), requester );
635 (*add) ( &userTime, sizeof (userTime), requester ); 635 (*add) ( &userTime, sizeof (userTime), requester );
636 636
637 handle = GetCurrentProcess (); 637 handle = GetCurrentProcess ();
638 GetProcessTimes (handle, &creationTime, &exitTime, 638 GetProcessTimes (handle, &creationTime, &exitTime,
639 &kernelTime, &userTime); 639 &kernelTime, &userTime);
640 (*add) ( &creationTime, sizeof (creationTime), requester ); 640 (*add) ( &creationTime, sizeof (creationTime), requester );
641 (*add) ( &exitTime, sizeof (exitTime), requester ); 641 (*add) ( &exitTime, sizeof (exitTime), requester );
642 (*add) ( &kernelTime, sizeof (kernelTime), requester ); 642 (*add) ( &kernelTime, sizeof (kernelTime), requester );
643 (*add) ( &userTime, sizeof (userTime), requester ); 643 (*add) ( &userTime, sizeof (userTime), requester );
644 644
645 /* Get the minimum and maximum working set size for the 645 /* Get the minimum and maximum working set size for the
646 current process */ 646 current process */
647 GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, 647 GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
648 &maximumWorkingSetSize); 648 &maximumWorkingSetSize);
649 (*add) ( &minimumWorkingSetSize, 649 (*add) ( &minimumWorkingSetSize,
650 sizeof (minimumWorkingSetSize), requester ); 650 sizeof (minimumWorkingSetSize), requester );
651 (*add) ( &maximumWorkingSetSize, 651 (*add) ( &maximumWorkingSetSize,
652 sizeof (maximumWorkingSetSize), requester ); 652 sizeof (maximumWorkingSetSize), requester );
653 } 653 }
654 654
655 655
656 /* The following are fixed for the lifetime of the process so we only 656 /* The following are fixed for the lifetime of the process so we only
657 * add them once */ 657 * add them once */
658 if (!addedFixedItems) { 658 if (!addedFixedItems) {
659 STARTUPINFO startupInfo; 659 STARTUPINFO startupInfo;
660 660
661 /* Get name of desktop, console window title, new window position and 661 /* Get name of desktop, console window title, new window position and
662 * size, window flags, and handles for stdin, stdout, and stderr */ 662 * size, window flags, and handles for stdin, stdout, and stderr */
663 startupInfo.cb = sizeof (STARTUPINFO); 663 startupInfo.cb = sizeof (STARTUPINFO);
664 GetStartupInfo (&startupInfo); 664 GetStartupInfo (&startupInfo);
665 (*add) ( &startupInfo, sizeof (STARTUPINFO), requester ); 665 (*add) ( &startupInfo, sizeof (STARTUPINFO), requester );
666 addedFixedItems = 1; 666 addedFixedItems = 1;
667 } 667 }
668 668
669 /* The performance of QPC varies depending on the architecture it's 669 /* The performance of QPC varies depending on the architecture it's
670 * running on and on the OS. Under NT it reads the CPU's 64-bit timestamp 670 * running on and on the OS. Under NT it reads the CPU's 64-bit timestamp
671 * counter (at least on a Pentium and newer '486's, it hasn't been tested 671 * counter (at least on a Pentium and newer '486's, it hasn't been tested
672 * on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC 672 * on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC
673 * timer. There are vague mumblings in the docs that it may fail if the 673 * timer. There are vague mumblings in the docs that it may fail if the
674 * appropriate hardware isn't available (possibly '386's or MIPS machines 674 * appropriate hardware isn't available (possibly '386's or MIPS machines
675 * running NT), but who's going to run NT on a '386? */ 675 * running NT), but who's going to run NT on a '386? */
676 { LARGE_INTEGER performanceCount; 676 { LARGE_INTEGER performanceCount;
677 if (QueryPerformanceCounter (&performanceCount)) { 677 if (QueryPerformanceCounter (&performanceCount)) {
678 if ( debug_me ) 678 if ( debug_me )
679 log_debug ("rndw32#gather_random_fast: perf data\n"); 679 log_debug ("rndw32#gather_random_fast: perf data\n");
680 (*add) (&performanceCount, sizeof (performanceCount), requester); 680 (*add) (&performanceCount, sizeof (performanceCount), requester);
681 } 681 }
682 else { /* Millisecond accuracy at best... */ 682 else { /* Millisecond accuracy at best... */
683 DWORD aword = GetTickCount (); 683 DWORD aword = GetTickCount ();
684 (*add) (&aword, sizeof (aword), requester ); 684 (*add) (&aword, sizeof (aword), requester );
685 } 685 }
686 } 686 }
687 687
688 return 0; 688 return 0;
689} 689}
690 690