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

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

unix.superglobalmegacorp.com

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