|
|
1.1.1.3 root 1: /* The source code contained in this file has been derived from the source code
2: of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
3: additions to that source code contained in this file are Copyright (c) 2004
1.1.1.4 ! root 4: TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
1.1.1.3 root 5: parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
6: release. Please see the file license.txt for full license details. */
1.1 root 7:
8: #include "TCdefs.h"
9:
10: #include <tlhelp32.h>
11:
12: #include "crypto.h"
13: #include "crc.h"
14: #include "random.h"
15: #include "apidrvr.h"
16: #include "dlgcode.h"
17:
18:
19: /* random management defines & pool pointers */
20: #define POOLSIZE 256
21: #define RANDOMPOOL_ALLOCSIZE ( ( POOLSIZE + SHA_DIGESTSIZE - 1 ) \
22: / SHA_DIGESTSIZE ) * SHA_DIGESTSIZE
23:
24: unsigned char *pRandPool = NULL;
1.1.1.2 root 25: int nRandIndex = 0, randPoolReadIndex = 0;
1.1 root 26:
1.1.1.3 root 27: int hashFunction = SHA1;
28:
1.1 root 29: /* Macro to add a single byte to the pool */
30: #define RandaddByte(x) {\
31: if (nRandIndex==POOLSIZE) nRandIndex = 0;\
32: pRandPool[nRandIndex] = (unsigned char) ((unsigned char)x + pRandPool[nRandIndex]); \
33: nRandIndex++; \
34: Randmix(); \
35: }
36:
37: /* Macro to add four bytes to the pool */
38: #define RandaddLong(x) _RandaddLong((unsigned long)x);
39:
40: #pragma warning( disable : 4710 ) /* inline func. not expanded warning */
41:
42: _inline void _RandaddLong(unsigned long x)
43: {
44: RandaddByte(x);
45: RandaddByte((x >> 8));
46: RandaddByte((x >> 16));
47: RandaddByte((x >> 24));
48: }
49:
50: HHOOK hMouse = NULL; /* Mouse hook for the random number generator */
51: HHOOK hKeyboard = NULL; /* Keyboard hook for the random number
52: generator */
53:
54: /* Variables for thread control, the thread is used to gather up info about
55: the system in in the background */
56: CRITICAL_SECTION critRandProt; /* The critical section */
57: BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among
58: thread's so its made volatile */
59: BOOL bDidSlowPoll = FALSE; /* We do the slow poll only once */
60:
61: /* Network library handle for the slowPollWinNT function */
62: HANDLE hNetAPI32 = NULL;
63:
1.1.1.4 ! root 64: // CryptoAPI
! 65: HCRYPTPROV hCryptProv;
! 66: unsigned __int8 buffer[POOLSIZE];
! 67:
1.1 root 68: BOOL bRandDidInit = FALSE;
69:
70: /* Init the random number generator, setup the hooks, and start the thread */
71: int
72: Randinit ()
73: {
74: HANDLE threadID;
75:
76: if(bRandDidInit == TRUE) return 0;
77:
78: InitializeCriticalSection (&critRandProt);
79:
80: bRandDidInit = TRUE;
81:
82: pRandPool = (unsigned char *) TCalloc (RANDOMPOOL_ALLOCSIZE);
83: if (pRandPool == NULL)
84: goto error;
85: else
86: memset (pRandPool, 0, RANDOMPOOL_ALLOCSIZE);
87:
1.1.1.2 root 88: VirtualLock (pRandPool, RANDOMPOOL_ALLOCSIZE);
89:
1.1 root 90: hKeyboard = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)&KeyboardProc, NULL, GetCurrentThreadId ());
1.1.1.4 ! root 91: if (hKeyboard == 0) handleWin32Error (0);
! 92:
! 93: hMouse = SetWindowsHookEx (WH_MOUSE, (HOOKPROC)&MouseProc, NULL, GetCurrentThreadId ());
! 94: if (hMouse == 0)
! 95: {
! 96: handleWin32Error (0);
1.1 root 97: goto error;
1.1.1.4 ! root 98: }
! 99:
! 100: if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)
! 101: && !CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
! 102: {
! 103: handleWin32Error (0);
! 104: }
1.1 root 105:
106: threadID = (HANDLE) _beginthread (ThreadSafeThreadFunction, 8192, NULL);
107: if (threadID == (HANDLE) - 1)
108: goto error;
109:
110: return 0;
111:
1.1.1.4 ! root 112: error:
1.1 root 113: Randfree ();
114: return 1;
115: }
116:
117: /* Close everything down, including the thread which is closed down by
118: setting a flag which eventually causes the thread function to exit */
119: void
120: Randfree ()
121: {
122: if (bRandDidInit == FALSE)
123: return;
124:
125: EnterCriticalSection (&critRandProt);
126:
127: if (hMouse != 0)
128: UnhookWindowsHookEx (hMouse);
129: if (hKeyboard != 0)
130: UnhookWindowsHookEx (hKeyboard);
131:
132: bThreadTerminate = TRUE;
133:
134: LeaveCriticalSection (&critRandProt);
135:
136: for (;;)
137: {
138: Sleep (250);
139: EnterCriticalSection (&critRandProt);
140: if (bThreadTerminate == FALSE)
141: {
142: LeaveCriticalSection (&critRandProt);
143: break;
144: }
145: LeaveCriticalSection (&critRandProt);
146: }
147:
148: if (pRandPool != NULL)
149: {
150: burn (pRandPool, RANDOMPOOL_ALLOCSIZE);
151: TCfree (pRandPool);
152: pRandPool = NULL;
153: }
154:
155: if (hNetAPI32 != 0)
156: {
157: FreeLibrary (hNetAPI32);
158: hNetAPI32 = NULL;
159: }
160:
1.1.1.4 ! root 161: if (hCryptProv)
! 162: {
! 163: CryptReleaseContext (hCryptProv, 0);
! 164: hCryptProv = 0;
! 165: }
! 166:
1.1 root 167: hMouse = NULL;
168: hKeyboard = NULL;
169: nRandIndex = 0;
170: bThreadTerminate = FALSE;
171: DeleteCriticalSection (&critRandProt);
172: bRandDidInit = FALSE;
173: }
174:
1.1.1.3 root 175: void RandSetHashFunction (int hash)
176: {
177: hashFunction = hash;
178: }
179:
1.1 root 180: /* Mix random pool with the hash function */
181: void
182: Randmix ()
183: {
184: int i;
185:
186: for (i = 0; i < POOLSIZE; i += SHA_DIGESTSIZE)
187: {
188: unsigned char inputBuffer[SHA_BLOCKSIZE];
189: int j;
190:
191: /* Copy SHA_BLOCKSIZE bytes from the circular buffer into the
192: hash data buffer, hash the data, and copy the result back
193: into the random pool */
194: for (j = 0; j < SHA_BLOCKSIZE; j++)
195: inputBuffer[j] = pRandPool[(i + j) % POOLSIZE];
1.1.1.3 root 196:
197: if (hashFunction == SHA1)
198: SHA1TRANSFORM ((unsigned long *) (pRandPool + i), inputBuffer);
199: else
200: RMD160Transform ((unsigned long *) (pRandPool + i), inputBuffer);
201:
1.1 root 202: memset (inputBuffer, 0, SHA_BLOCKSIZE);
203: }
204: }
205:
206: /* Add a buffer to the pool */
207: void
208: RandaddBuf (void *buf, int len)
209: {
210: int i;
211: for (i = 0; i < len; i++)
212: {
213: RandaddByte (((unsigned char *) buf)[i]);
214: }
215: }
216:
217: void
1.1.1.4 ! root 218: RandpeekBytes (unsigned char *buf, int len)
1.1 root 219: {
220: EnterCriticalSection (&critRandProt);
221: memcpy (buf, pRandPool, len);
222: LeaveCriticalSection (&critRandProt);
223: }
224:
225: /* Get a certain amount of true random bytes from the pool */
226: void
1.1.1.4 ! root 227: RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll)
1.1 root 228: {
229: int i;
230:
231: EnterCriticalSection (&critRandProt);
232:
1.1.1.2 root 233: if (bDidSlowPoll == FALSE || forceSlowPoll)
1.1 root 234: {
235: bDidSlowPoll = TRUE;
1.1.1.2 root 236: SlowPollWinNT ();
1.1 root 237: }
1.1.1.2 root 238:
239: FastPoll ();
1.1 root 240:
241: /* There's never more than POOLSIZE worth of randomess */
242: if (len > POOLSIZE)
243: len = POOLSIZE;
244:
1.1.1.2 root 245: // Requested number of bytes is copied from pool to output buffer,
246: // pool is rehashed, and output buffer is XORed with new data from pool
247: for (i = 0; i < len; i++)
248: {
249: buf[i] = pRandPool[randPoolReadIndex++];
250: if (randPoolReadIndex == POOLSIZE) randPoolReadIndex = 0;
251: }
252:
1.1 root 253: /* Now invert the pool */
254: for (i = 0; i < POOLSIZE / 4; i++)
255: {
256: ((unsigned long *) pRandPool)[i] = ~((unsigned long *) pRandPool)[i];
257: }
258:
259: /* Now remix the pool, creating the new pool */
1.1.1.4 ! root 260: FastPoll ();
! 261:
! 262: for (i = 0; i < len; i++)
! 263: {
! 264: buf[i] ^= pRandPool[randPoolReadIndex++];
! 265: if (randPoolReadIndex == POOLSIZE) randPoolReadIndex = 0;
! 266: }
1.1 root 267:
268: LeaveCriticalSection (&critRandProt);
269: }
270:
271: /* Capture the mouse, and as long as the event is not the same as the last
272: two events :- add a crc of the event, and a crc of the time difference
273: between this event and the last + the current time to the pool */
274: LRESULT CALLBACK
275: MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
276: {
277: static DWORD dwLastTimer;
278: static unsigned long lastCrc, lastCrc2;
279: MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam;
280:
281: if (nCode < 0)
282: return CallNextHookEx (hMouse, nCode, wParam, lParam);
283: else
284: {
285: DWORD dwTimer = GetTickCount ();
286: DWORD j = dwLastTimer - dwTimer;
287: unsigned long crc = 0L;
288: int i;
289:
290: dwLastTimer = dwTimer;
291:
292: for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++)
293: {
294: crc = UPDC32 (((unsigned char *) lpMouse)[i], crc);
295: }
296:
297: if (crc != lastCrc && crc != lastCrc2)
298: {
299: unsigned long timeCrc = 0L;
300:
301: for (i = 0; i < 4; i++)
302: {
303: timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
304: }
305:
306: for (i = 0; i < 4; i++)
307: {
308: timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
309: }
310:
311: EnterCriticalSection (&critRandProt);
312: RandaddLong (timeCrc);
313: RandaddLong (crc);
314: LeaveCriticalSection (&critRandProt);
315: }
316: lastCrc2 = lastCrc;
317: lastCrc = crc;
318:
319: }
320: return 0;
321: }
322:
323: /* Capture the keyboard, as long as the event is not the same as the last two
324: events :- add a crc of the event to the pool along with a crc of the time
325: difference between this event and the last */
326: LRESULT CALLBACK
327: KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
328: {
329: static int lLastKey, lLastKey2;
330: static DWORD dwLastTimer;
331: int nKey = (lParam & 0x00ff0000) >> 16;
332: int nCapture = 0;
333:
334: if (nCode < 0)
335: return CallNextHookEx (hMouse, nCode, wParam, lParam);
336:
337: if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
338: (lParam & 0x80000000))
339: {
340: if (nKey != lLastKey)
341: nCapture = 1; /* Capture this key */
342: else if (nKey != lLastKey2)
343: nCapture = 1; /* Allow for one repeat */
344: }
345: if (nCapture)
346: {
347: DWORD dwTimer = GetTickCount ();
348: DWORD j = dwLastTimer - dwTimer;
349: unsigned long timeCrc = 0L;
350: int i;
351:
352: dwLastTimer = dwTimer;
353: lLastKey2 = lLastKey;
354: lLastKey = nKey;
355:
356: for (i = 0; i < 4; i++)
357: {
358: timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
359: }
360:
361: for (i = 0; i < 4; i++)
362: {
363: timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
364: }
365:
366: EnterCriticalSection (&critRandProt);
367: RandaddLong (lParam);
368: RandaddLong (timeCrc);
369: LeaveCriticalSection (&critRandProt);
370: }
371: return 0;
372: }
373:
374: /* This is the thread function which will poll the system for randomness */
375: void
376: ThreadSafeThreadFunction (void *dummy)
377: {
378: if (dummy); /* Remove unused parameter warning */
379:
380: for (;;)
381: {
382: EnterCriticalSection (&critRandProt);
383:
384: if (bThreadTerminate == TRUE)
385: {
386: bThreadTerminate = FALSE;
387: LeaveCriticalSection (&critRandProt);
388: _endthread ();
389: }
390: else
391: {
392: FastPoll ();
393: }
394:
395: LeaveCriticalSection (&critRandProt);
396:
397: Sleep (250);
398: }
399: }
400:
401: /* Type definitions for function pointers to call NetAPI32 functions */
402:
403: typedef
404: DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
405: DWORD dwLevel, DWORD dwOptions,
406: LPBYTE * lpBuffer);
407: typedef
408: DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
409: typedef
410: DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
411:
412: NETSTATISTICSGET pNetStatisticsGet = NULL;
413: NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
414: NETAPIBUFFERFREE pNetApiBufferFree = NULL;
415:
416: /* This is the slowpoll function which gathers up network/hard drive
417: performance data for the random pool */
418: void
419: SlowPollWinNT (void)
420: {
421: static int isWorkstation = -1;
422: PPERF_DATA_BLOCK pPerfData;
423: static int cbPerfData = 0x10000;
424: HANDLE hDevice;
425: LPBYTE lpBuffer;
426: DWORD dwSize, status;
427: LPWSTR lpszLanW, lpszLanS;
1.1.1.4 ! root 428: int i, nDrive;
1.1 root 429:
430: /* Find out whether this is an NT server or workstation if necessary */
431: if (isWorkstation == -1)
432: {
433: HKEY hKey;
434:
435: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
436: "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
437: 0, KEY_READ, &hKey) == ERROR_SUCCESS)
438: {
439: unsigned char szValue[32];
440: dwSize = sizeof (szValue);
441:
442: isWorkstation = TRUE;
443: status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
444: szValue, &dwSize);
445:
446: if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
447: /* Note: There are (at least) three cases for
448: ProductType: WinNT = NT Workstation,
449: ServerNT = NT Server, LanmanNT = NT Server
450: acting as a Domain Controller */
451: isWorkstation = FALSE;
452:
453: RegCloseKey (hKey);
454: }
455: }
456: /* Initialize the NetAPI32 function pointers if necessary */
457: if (hNetAPI32 == NULL)
458: {
459: /* Obtain a handle to the module containing the Lan Manager
460: functions */
461: hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
462: if (hNetAPI32 != NULL)
463: {
464: /* Now get pointers to the functions */
465: pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
466: "NetStatisticsGet");
467: pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
468: "NetApiBufferSize");
469: pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
470: "NetApiBufferFree");
471:
472: /* Make sure we got valid pointers for every NetAPI32
473: function */
474: if (pNetStatisticsGet == NULL ||
475: pNetApiBufferSize == NULL ||
476: pNetApiBufferFree == NULL)
477: {
478: /* Free the library reference and reset the
479: static handle */
480: FreeLibrary (hNetAPI32);
481: hNetAPI32 = NULL;
482: }
483: }
484: }
485:
486: /* Get network statistics. Note: Both NT Workstation and NT Server
487: by default will be running both the workstation and server
488: services. The heuristic below is probably useful though on the
489: assumption that the majority of the network traffic will be via
490: the appropriate service */
491: lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
492: lpszLanS = (LPWSTR) WIDE ("LanmanServer");
493: if (hNetAPI32 &&
494: pNetStatisticsGet (NULL,
495: isWorkstation ? lpszLanW : lpszLanS,
496: 0, 0, &lpBuffer) == 0)
497: {
498: pNetApiBufferSize (lpBuffer, &dwSize);
499: RandaddBuf ((unsigned char *) lpBuffer, dwSize);
500: pNetApiBufferFree (lpBuffer);
501: }
502:
503: /* Get disk I/O statistics for all the hard drives */
504: for (nDrive = 0;; nDrive++)
505: {
506: DISK_PERFORMANCE diskPerformance;
507: char szDevice[24];
508:
509: /* Check whether we can access this device */
510: sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
511: hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
512: NULL, OPEN_EXISTING, 0, NULL);
513: if (hDevice == INVALID_HANDLE_VALUE)
514: break;
515:
516:
517: /* Note: This only works if you have turned on the disk
518: performance counters with 'diskperf -y'. These counters
519: are off by default */
520: if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
521: &diskPerformance, sizeof (DISK_PERFORMANCE),
522: &dwSize, NULL))
523: {
524: RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
525: }
526: CloseHandle (hDevice);
527: }
528:
1.1.1.4 ! root 529: // CryptoAPI
! 530: for (i = 0; i < 100; i++)
! 531: {
! 532: if (CryptGenRandom(hCryptProv, sizeof (buffer), buffer))
! 533: RandaddBuf (buffer, sizeof (buffer));
1.1 root 534: }
535: }
536:
537:
538: /* Win9x typedefs and variables for toolhelp32 use */
539: typedef BOOL (WINAPI * MODULEWALK) (HANDLE hSnapshot, LPMODULEENTRY32 lpme);
540: typedef BOOL (WINAPI * THREADWALK) (HANDLE hSnapshot, LPTHREADENTRY32 lpte);
541: typedef BOOL (WINAPI * PROCESSWALK) (HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
542: typedef BOOL (WINAPI * HEAPLISTWALK) (HANDLE hSnapshot, LPHEAPLIST32 lphl);
543: typedef BOOL (WINAPI * HEAPFIRST) (LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID);
544: typedef BOOL (WINAPI * HEAPNEXT) (LPHEAPENTRY32 lphe);
545: typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD dwFlags, DWORD th32ProcessID);
546: CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
547: MODULEWALK pModule32First = NULL;
548: MODULEWALK pModule32Next = NULL;
549: PROCESSWALK pProcess32First = NULL;
550: PROCESSWALK pProcess32Next = NULL;
551: THREADWALK pThread32First = NULL;
552: THREADWALK pThread32Next = NULL;
553: HEAPLISTWALK pHeap32ListFirst = NULL;
554: HEAPLISTWALK pHeap32ListNext = NULL;
555: HEAPFIRST pHeap32First = NULL;
556: HEAPNEXT pHeap32Next = NULL;
557:
558: void
559: SlowPollWin9x (void)
560: {
561: PROCESSENTRY32 pe32;
562: THREADENTRY32 te32;
563: MODULEENTRY32 me32;
564: HEAPLIST32 hl32;
565: HANDLE hSnapshot;
566:
567: /* Initialize the Toolhelp32 function pointers if necessary */
568: if (pCreateToolhelp32Snapshot == NULL)
569: {
570: HANDLE hKernel = NULL;
571:
572: /* Obtain the module handle of the kernel to retrieve the
573: addresses of the Toolhelp32 functions */
574: if ((hKernel = GetModuleHandle ("KERNEL32.DLL")) == NULL)
575: return;
576:
577: /* Now get pointers to the functions */
578: pCreateToolhelp32Snapshot = (CREATESNAPSHOT) GetProcAddress (hKernel,
579: "CreateToolhelp32Snapshot");
580: pModule32First = (MODULEWALK) GetProcAddress (hKernel,
581: "Module32First");
582: pModule32Next = (MODULEWALK) GetProcAddress (hKernel,
583: "Module32Next");
584: pProcess32First = (PROCESSWALK) GetProcAddress (hKernel,
585: "Process32First");
586: pProcess32Next = (PROCESSWALK) GetProcAddress (hKernel,
587: "Process32Next");
588: pThread32First = (THREADWALK) GetProcAddress (hKernel,
589: "Thread32First");
590: pThread32Next = (THREADWALK) GetProcAddress (hKernel,
591: "Thread32Next");
592: pHeap32ListFirst = (HEAPLISTWALK) GetProcAddress (hKernel,
593: "Heap32ListFirst");
594: pHeap32ListNext = (HEAPLISTWALK) GetProcAddress (hKernel,
595: "Heap32ListNext");
596: pHeap32First = (HEAPFIRST) GetProcAddress (hKernel,
597: "Heap32First");
598: pHeap32Next = (HEAPNEXT) GetProcAddress (hKernel,
599: "Heap32Next");
600:
601: /* Make sure we got valid pointers for every Toolhelp32
602: function */
603: if (pModule32First == NULL || pModule32Next == NULL || \
604: pProcess32First == NULL || pProcess32Next == NULL || \
605: pThread32First == NULL || pThread32Next == NULL || \
606: pHeap32ListFirst == NULL || pHeap32ListNext == NULL || \
607: pHeap32First == NULL || pHeap32Next == NULL || \
608: pCreateToolhelp32Snapshot == NULL)
609: {
610: /* Mark the main function as unavailable in case for
611: future reference */
612: pCreateToolhelp32Snapshot = NULL;
613: return;
614: }
615: }
616:
617: /* Take a snapshot of everything we can get to which is currently in
618: the system */
619: hSnapshot = pCreateToolhelp32Snapshot (TH32CS_SNAPALL, 0);
620: if (!hSnapshot)
621: return;
622:
623: /* Walk through the local heap */
624: hl32.dwSize = sizeof (HEAPLIST32);
625: if (pHeap32ListFirst (hSnapshot, &hl32))
626: do
627: {
628: HEAPENTRY32 he32;
629:
630: /* First add the information from the basic
631: Heaplist32 structure */
632: RandaddBuf ((BYTE *) & hl32, sizeof (HEAPLIST32));
633:
634: /* Now walk through the heap blocks getting
635: information on each of them */
636: he32.dwSize = sizeof (HEAPENTRY32);
637: if (pHeap32First (&he32, hl32.th32ProcessID, hl32.th32HeapID))
638: do
639: {
640: RandaddBuf ((BYTE *) & he32, sizeof (HEAPENTRY32));
641: }
642: while (pHeap32Next (&he32));
643: }
644: while (pHeap32ListNext (hSnapshot, &hl32));
645:
646: /* Walk through all processes */
647: pe32.dwSize = sizeof (PROCESSENTRY32);
648: if (pProcess32First (hSnapshot, &pe32))
649: do
650: {
651: RandaddBuf ((BYTE *) & pe32, sizeof (PROCESSENTRY32));
652: }
653: while (pProcess32Next (hSnapshot, &pe32));
654:
655: /* Walk through all threads */
656: te32.dwSize = sizeof (THREADENTRY32);
657: if (pThread32First (hSnapshot, &te32))
658: do
659: {
660: RandaddBuf ((BYTE *) & te32, sizeof (THREADENTRY32));
661: }
662: while (pThread32Next (hSnapshot, &te32));
663:
664: /* Walk through all modules associated with the process */
665: me32.dwSize = sizeof (MODULEENTRY32);
666: if (pModule32First (hSnapshot, &me32))
667: do
668: {
669: RandaddBuf ((BYTE *) & me32, sizeof (MODULEENTRY32));
670: }
671: while (pModule32Next (hSnapshot, &me32));
672:
673: /* Clean up the snapshot */
674: CloseHandle (hSnapshot);
675: }
676:
677:
678:
679: /* This is the fastpoll function which gathers up info by calling various
680: api's */
681: void
682: FastPoll (void)
683: {
684: static BOOL addedFixedItems = FALSE;
685: FILETIME creationTime, exitTime, kernelTime, userTime;
686: DWORD minimumWorkingSetSize, maximumWorkingSetSize;
687: LARGE_INTEGER performanceCount;
688: MEMORYSTATUS memoryStatus;
689: HANDLE handle;
690: POINT point;
691:
692: /* Get various basic pieces of system information */
693: RandaddLong (GetActiveWindow ()); /* Handle of active window */
694: RandaddLong (GetCapture ()); /* Handle of window with mouse
695: capture */
696: RandaddLong (GetClipboardOwner ()); /* Handle of clipboard owner */
697: RandaddLong (GetClipboardViewer ()); /* Handle of start of
698: clpbd.viewer list */
699: RandaddLong (GetCurrentProcess ()); /* Pseudohandle of current
700: process */
701: RandaddLong (GetCurrentProcessId ()); /* Current process ID */
702: RandaddLong (GetCurrentThread ()); /* Pseudohandle of current
703: thread */
704: RandaddLong (GetCurrentThreadId ()); /* Current thread ID */
705: RandaddLong (GetCurrentTime ()); /* Milliseconds since Windows
706: started */
707: RandaddLong (GetDesktopWindow ()); /* Handle of desktop window */
708: RandaddLong (GetFocus ()); /* Handle of window with kb.focus */
709: RandaddLong (GetInputState ()); /* Whether sys.queue has any events */
710: RandaddLong (GetMessagePos ()); /* Cursor pos.for last message */
711: RandaddLong (GetMessageTime ()); /* 1 ms time for last message */
712: RandaddLong (GetOpenClipboardWindow ()); /* Handle of window with
713: clpbd.open */
714: RandaddLong (GetProcessHeap ()); /* Handle of process heap */
715: RandaddLong (GetProcessWindowStation ()); /* Handle of procs
716: window station */
717: RandaddLong (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in
718: input queue */
719:
720: /* Get multiword system information */
721: GetCaretPos (&point); /* Current caret position */
722: RandaddBuf ((unsigned char *) &point, sizeof (POINT));
723: GetCursorPos (&point); /* Current mouse cursor position */
724: RandaddBuf ((unsigned char *) &point, sizeof (POINT));
725:
726: /* Get percent of memory in use, bytes of physical memory, bytes of
727: free physical memory, bytes in paging file, free bytes in paging
728: file, user bytes of address space, and free user bytes */
729: memoryStatus.dwLength = sizeof (MEMORYSTATUS);
730: GlobalMemoryStatus (&memoryStatus);
731: RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));
732:
733: /* Get thread and process creation time, exit time, time in kernel
734: mode, and time in user mode in 100ns intervals */
735: handle = GetCurrentThread ();
736: GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
737: RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
738: RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
739: RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
740: RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
741: handle = GetCurrentProcess ();
742: GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
743: RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
744: RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
745: RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
746: RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
747:
748: /* Get the minimum and maximum working set size for the current
749: process */
750: GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
751: &maximumWorkingSetSize);
752: RandaddLong (minimumWorkingSetSize);
753: RandaddLong (maximumWorkingSetSize);
754:
755: /* The following are fixed for the lifetime of the process so we only
756: add them once */
757: if (addedFixedItems == 0)
758: {
759: STARTUPINFO startupInfo;
760:
761: /* Get name of desktop, console window title, new window
762: position and size, window flags, and handles for stdin,
763: stdout, and stderr */
764: startupInfo.cb = sizeof (STARTUPINFO);
765: GetStartupInfo (&startupInfo);
766: RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
767: addedFixedItems = TRUE;
768: }
769: /* The docs say QPC can fail if appropriate hardware is not
770: available. It works on 486 & Pentium boxes, but hasn't been tested
771: for 386 or RISC boxes */
772: if (QueryPerformanceCounter (&performanceCount))
773: RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
774: else
775: {
776: /* Millisecond accuracy at best... */
777: DWORD dwTicks = GetTickCount ();
778: RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
779: }
1.1.1.4 ! root 780:
! 781: // CryptoAPI
! 782: if (CryptGenRandom(hCryptProv, sizeof (buffer), buffer))
! 783: RandaddBuf (buffer, sizeof (buffer));
1.1 root 784: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.