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