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