|
|
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.