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