void slowPoll( void ) { fastPoll(); fastPoll(); fastPoll(); fastPoll(); fastPoll(); }
void slowPoll( void ) { static BOOLEAN addedFixedItems = FALSE; RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; int taskID, value, status; status = initRandomData( randomState, buffer, RANDOM_BUFSIZE ); if( cryptStatusError( status ) ) retIntError_Void(); /* The following are fixed for the lifetime of the process (and in fact for the BSP as a whole) so we only add them once */ if( !addedFixedItems ) { const char *string; int value; /* Add the model name of the CPU board and the BSP version and revision number */ string = sysModel(); if( string != NULL ) addRandomData( randomState, string, strlen( string ) ); string = sysBspRev(); if( string != NULL ) addRandomData( randomState, string, strlen( string ) ); value = sysProcNumGet(); /* Usually 0 */ addRandomLong( randomState, value ); } /* Add the current task ID and task options. The task options are relatively fixed but the task ID seems quite random and over the full 32-bit range */ taskID = taskIdSelf(); addRandomLong( randomState, taskID ); status = taskOptionsGet( taskID, &value ); if( status == OK ) addRandomLong( randomState, value ); endRandomData( randomState, 3 ); fastPoll(); }
static void slowPollWinCE( void ) { PROCESSENTRY32 pe32; THREADENTRY32 te32; MODULEENTRY32 me32; HEAPLIST32 hl32; HANDLE hSnapshot; RANDOM_STATE randomState; BYTE buffer[ BIG_RANDOM_BUFSIZE ]; int iterationCount; /* Initialize the Toolhelp32 function pointers if necessary. The Toolhelp DLL isn't always present (some OEMs omit it) so we have to link it dynamically */ if( hToolHelp32 == NULL ) { /* Obtain the module handle of the kernel to retrieve the addresses of the ToolHelp32 functions */ if( ( hToolHelp32 = LoadLibrary( TEXT( "Toolhelp.dll" ) ) ) == NULL ) { /* There's no ToolHelp32 available, now we're in a bit of a bind. Try for at least a fast poll */ fastPoll(); return; } /* Now get pointers to the functions */ pCreateToolhelp32Snapshot = ( CREATESNAPSHOT ) GetProcAddress( hToolHelp32, TEXT( "CreateToolhelp32Snapshot" ) ); pCloseToolhelp32Snapshot = ( CLOSESNAPSHOT ) GetProcAddress( hToolHelp32, TEXT( "CloseToolhelp32Snapshot" ) ); pModule32First = ( MODULEWALK ) GetProcAddress( hToolHelp32, TEXT( "Module32First" ) ); pModule32Next = ( MODULEWALK ) GetProcAddress( hToolHelp32, TEXT( "Module32Next" ) ); pProcess32First = ( PROCESSWALK ) GetProcAddress( hToolHelp32, TEXT( "Process32First" ) ); pProcess32Next = ( PROCESSWALK ) GetProcAddress( hToolHelp32, TEXT( "Process32Next" ) ); pThread32First = ( THREADWALK ) GetProcAddress( hToolHelp32, TEXT( "Thread32First" ) ); pThread32Next = ( THREADWALK ) GetProcAddress( hToolHelp32, TEXT( "Thread32Next" ) ); pHeap32ListFirst = ( HEAPLISTWALK ) GetProcAddress( hToolHelp32, TEXT( "Heap32ListFirst" ) ); pHeap32ListNext = ( HEAPLISTWALK ) GetProcAddress( hToolHelp32, TEXT( "Heap32ListNext" ) ); pHeap32First = ( HEAPFIRST ) GetProcAddress( hToolHelp32, TEXT( "Heap32First" ) ); pHeap32Next = ( HEAPNEXT ) GetProcAddress( hToolHelp32, TEXT( "Heap32Next" ) ); /* Make sure we got valid pointers for every Toolhelp32 function */ if( pModule32First == NULL || pModule32Next == NULL || \ pProcess32First == NULL || pProcess32Next == NULL || \ pThread32First == NULL || pThread32Next == NULL || \ pHeap32ListFirst == NULL || pHeap32ListNext == NULL || \ pHeap32First == NULL || pHeap32Next == NULL || \ pCreateToolhelp32Snapshot == NULL ) { /* Mark the main function as unavailable in case for future reference */ pCreateToolhelp32Snapshot = NULL; return; } } if( krnlIsExiting() ) return; initRandomData( randomState, buffer, BIG_RANDOM_BUFSIZE ); /* Take snapshots what's currently in the system. In theory we could do a TH32CS_SNAPALL to get everything at once, but this can lead to out-of-memory errors on some memory-limited systems, so we only snapshot the individual resource that we're interested in. First we walk through the local heap. We have to be careful to not spend excessive amounts of time on this if we're linked into a large application with a great many heaps and/or heap blocks, since the heap-traversal functions are rather slow. Fortunately this is quite rare under WinCE since it implies a large/long-running server app, which we're unlikely to run into. Ideally in order to prevent excessive delays we'd count the number of heaps and ensure that no_heaps * no_heap_blocks doesn't exceed some maximum value, however this requires two passes of (slow) heap traversal rather than one, which doesn't help the situation much. To provide at least some protection, we limit the total number of heaps and heap entries traversed, although this leads to slightly suboptimal performance if we have a small number of deep heaps rather than the current large number of shallow heaps. There is however a second consideration that needs to be taken into account when doing this, which is that the heap-management functions aren't completely thread-safe, so that under (very rare) conditions of heavy allocation/deallocation this can cause problems when calling HeapNext(). By limiting the amount of time that we spend in each heap, we can reduce our exposure somewhat */ hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPHEAPLIST, 0 ); if( hSnapshot == INVALID_HANDLE_VALUE ) { assert( DEBUG_WARN ); /* Make sure that we get some feedback */ return; } hl32.dwSize = sizeof( HEAPLIST32 ); if( pHeap32ListFirst( hSnapshot, &hl32 ) ) { int listCount = 0; do { HEAPENTRY32 he32; /* First add the information from the basic Heaplist32 structure */ if( krnlIsExiting() ) { pCloseToolhelp32Snapshot( hSnapshot ); return; } addRandomData( randomState, &hl32, sizeof( HEAPLIST32 ) ); /* Now walk through the heap blocks getting information on each of them */ he32.dwSize = sizeof( HEAPENTRY32 ); if( pHeap32First( hSnapshot, &he32, hl32.th32ProcessID, hl32.th32HeapID ) ) { int entryCount = 0; do { if( krnlIsExiting() ) { pCloseToolhelp32Snapshot( hSnapshot ); return; } addRandomData( randomState, &he32, sizeof( HEAPENTRY32 ) ); } while( entryCount++ < 20 && pHeap32Next( hSnapshot, &he32 ) ); } } while( listCount++ < 20 && pHeap32ListNext( hSnapshot, &hl32 ) ); } pCloseToolhelp32Snapshot( hSnapshot ); if( krnlIsExiting() ) return; /* Now walk through all processes */ hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if( hSnapshot == INVALID_HANDLE_VALUE ) { endRandomData( randomState, 40 ); return; } pe32.dwSize = sizeof( PROCESSENTRY32 ); iterationCount = 0; if( pProcess32First( hSnapshot, &pe32 ) ) { do { if( krnlIsExiting() ) { pCloseToolhelp32Snapshot( hSnapshot ); return; } addRandomData( randomState, &pe32, sizeof( PROCESSENTRY32 ) ); } while( pProcess32Next( hSnapshot, &pe32 ) && \ iterationCount++ < FAILSAFE_ITERATIONS_LARGE ); } pCloseToolhelp32Snapshot( hSnapshot ); if( krnlIsExiting() ) return; /* Then walk through all threads */ hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); if( hSnapshot == INVALID_HANDLE_VALUE ) { endRandomData( randomState, 60 ); return; } te32.dwSize = sizeof( THREADENTRY32 ); iterationCount = 0; if( pThread32First( hSnapshot, &te32 ) ) { do { if( krnlIsExiting() ) { pCloseToolhelp32Snapshot( hSnapshot ); return; } addRandomData( randomState, &te32, sizeof( THREADENTRY32 ) ); } while( pThread32Next( hSnapshot, &te32 ) && \ iterationCount++ < FAILSAFE_ITERATIONS_LARGE ); } pCloseToolhelp32Snapshot( hSnapshot ); if( krnlIsExiting() ) return; /* Finally, walk through all modules associated with the process */ hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, 0 ); if( hSnapshot == INVALID_HANDLE_VALUE ) { endRandomData( randomState, 80 ); return; } me32.dwSize = sizeof( MODULEENTRY32 ); iterationCount = 0; if( pModule32First( hSnapshot, &me32 ) ) { do { if( krnlIsExiting() ) { pCloseToolhelp32Snapshot( hSnapshot ); return; } addRandomData( randomState, &me32, sizeof( MODULEENTRY32 ) ); } while( pModule32Next( hSnapshot, &me32 ) && \ iterationCount++ < FAILSAFE_ITERATIONS_LARGE ); } pCloseToolhelp32Snapshot( hSnapshot ); if( krnlIsExiting() ) return; /* Flush any remaining data through */ endRandomData( randomState, 100 ); }