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

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

unix.superglobalmegacorp.com

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