Annotation of truecrypt/common/random.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.