void fastPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; struct timeval tv; system_info info; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); gettimeofday( &tv, NULL ); addRandomValue( randomState, tv.tv_sec ); addRandomValue( randomState, tv.tv_usec ); /* Get the number of microseconds since the user last provided any input to any part of the system, the state of keyboard shift keys */ #if 0 /* See comment at start */ bigtime_t idleTime; uint32 value; idleTime = idle_time(); addRandomData( randomState, &idleTime, sizeof( bigtime_t ) ); value = modifiers(); addRandomValue( randomState, value ); #endif /* 0 */ /* Get various fixed values (the 64-bit machine ID, CPU count and type(s), clock speed, platform type, etc) and variable resources (number of in- use pages, semaphores, ports, threads, teams, number of page faults, and number of microseconds the CPU has been active) */ get_system_info( &info ); addRandomData( randomState, &info, sizeof( info ) ); /* Flush any remaining data through */ endRandomData( randomState, 5 ); }
void slowPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE ]; MODULEENTRY moduleEntry; GLOBALENTRY globalEntry; TASKENTRY taskEntry; int count; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Walk the global heap getting information on each entry in it. This retrieves the objects linear address, size, handle, lock count, owner, object type, and segment type */ count = 0; globalEntry.dwSize = sizeof( GLOBALENTRY ); if( GlobalFirst( &globalEntry, GLOBAL_ALL ) ) do { addRandomData( randomState, &globalEntry, sizeof( GLOBALENTRY ) ); count++; } while( count < 70 && GlobalNext( &globalEntry, GLOBAL_ALL ) ); /* Walk the module list getting information on each entry in it. This retrieves the module name, handle, reference count, executable path, and next module */ count = 0; moduleEntry.dwSize = sizeof( MODULEENTRY ); if( ModuleFirst( &moduleEntry ) ) do { addRandomData( randomState, &moduleEntry, sizeof( MODULEENTRY ) ); count++; } while( count < 20 && ModuleNext( &moduleEntry ) ); /* Walk the task list getting information on each entry in it. This retrieves the task handle, parent task handle, instance handle, stack segment and offset, stack size, number of pending events, task queue, and the name of module executing the task. We also call TaskGetCSIP() for the code segment and offset of each task if it's safe to do so (note that this call can cause odd things to happen in debuggers and runtime code checkers because of the way TaskGetCSIP() is implemented) */ count = 0; taskEntry.dwSize = sizeof( TASKENTRY ); if( TaskFirst( &taskEntry ) ) do { addRandomData( randomState, &taskEntry, sizeof( TASKENTRY ) ); if( taskEntry.hTask != GetCurrentTask() ) addRandomValue( randomState, TaskGetCSIP( taskEntry.hTask ) ); count++; } while( count < 100 && TaskNext( &taskEntry ) ); /* Flush any remaining data through */ endRandomData( randomState, 100 ); }
void fastPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE ]; SYSHEAPINFO sysHeapInfo; MEMMANINFO memManInfo; TIMERINFO timerInfo; POINT point; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get various basic pieces of system information: Handle of the window with mouse capture, handle of window with input focus, amount of space in global heap, whether system queue has any events, cursor position for last message, 55 ms time for last message, number of active tasks, 55 ms time since Windows started, current mouse cursor position, current caret position */ addRandomValue( randomState, GetCapture() ); addRandomValue( randomState, GetFocus() ); addRandomValue( randomState, GetFreeSpace( 0 ) ); addRandomValue( randomState, GetInputState() ); addRandomValue( randomState, GetMessagePos() ); addRandomValue( randomState, GetMessageTime() ); addRandomValue( randomState, GetNumTasks() ); addRandomValue( randomState, GetTickCount() ); GetCursorPos( &point ); addRandomData( randomState, &point, sizeof( POINT ) ); GetCaretPos( &point ); addRandomData( randomState, &point, sizeof( POINT ) ); /* Get the largest free memory block, number of lockable pages, number of unlocked pages, number of free and used pages, and number of swapped pages */ memManInfo.dwSize = sizeof( MEMMANINFO ); MemManInfo( &memManInfo ); addRandomData( randomState, &memManInfo, sizeof( MEMMANINFO ) ); /* Get the execution times of the current task and VM to approximately 1ms resolution */ timerInfo.dwSize = sizeof( TIMERINFO ); TimerCount( &timerInfo ); addRandomData( randomState, &timerInfo, sizeof( TIMERINFO ) ); /* Get the percentage free and segment of the user and GDI heap */ sysHeapInfo.dwSize = sizeof( SYSHEAPINFO ); SystemHeapInfo( &sysHeapInfo ); addRandomData( randomState, &sysHeapInfo, sizeof( SYSHEAPINFO ) ); /* Flush any remaining data through */ endRandomData( randomState, 25 ); }
void fastPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; WinHandle winHandle; Coord xCoord, yCoord; Boolean flag; uint64_t ticks; nsecs_t nsTime; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get the event-available and low-level event-available flag, current pen status, and handle of the window with the input focus */ flag = EvtEventAvail(); addRandomValue( randomState, flag ); flag = EvtSysEventAvail( TRUE ); addRandomValue( randomState, flag ); EvtGetPen( &xCoord, &yCoord, &flag ); addRandomValue( randomState, xCoord ); addRandomValue( randomState, yCoord ); winHandle = EvtGetFocusWindow(); addRandomValue( randomState, winHandle ); /* Get the number of ticks of the (software) millisecond clock used by the scheduler, and the length of time in nanoseconds since the last reset */ ticks = TimGetTicks(); addRandomData( randomState, &ticks, sizeof( uint64_t ) ); nsTime = SysGetRunTime(); addRandomData( randomState, &nsTime, sizeof( nsecs_t ) ); /* Get the value of the real-time and runtime clocks in nanoseconds. One of these may just be a wrapper for SysGetRunTime(), in addition it's likely that they're hardware-specific, being CPU-level cycle counters of some kind */ nsTime = system_real_time(); addRandomData( randomState, &nsTime, sizeof( nsecs_t ) ); nsTime = system_time(); addRandomData( randomState, &nsTime, sizeof( nsecs_t ) ); /* Flush any remaining data through */ endRandomData( randomState, 5 ); }
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(); }
void fastPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; REG_SET registerSet; struct timespec timeSpec; ULONG tickCount; int value, status; status = initRandomData( randomState, buffer, RANDOM_BUFSIZE ); if( cryptStatusError( status ) ) retIntError_Void(); /* Add various clock/timer values. These are both very fast clocks/ counters, however the difference over subsequent calls is only 2-3 bits in the LSB */ tickCount = tickGet(); addRandomLong( randomState, tickCount ); status = clock_gettime( CLOCK_REALTIME, &timeSpec ); if( status == 0 ) addRandomData( randomState, &timeSpec, sizeof( struct timespec ) ); /* Add the interrupt nesting depth (usually 0) */ value = intCount(); addRandomLong( randomState, value ); /* Add the current task's registers. The documentation states that "self-examination is not advisable as results are unpredictable", which is either good (the registers are random garbage values) or bad (the registers have fixed values). Usually they seem to be pretty fixed, at least when called repeatedly in rapid succession */ status = taskRegsGet( taskIdSelf(), ®isterSet ); if( status == OK ) addRandomData( randomState, ®isterSet, sizeof( REG_SET ) ); endRandomData( randomState, 5 ); }
void fastPoll( void ) { static BOOLEAN addedFixedItems = FALSE, hasHardwareRNG = FALSE; static CEGENRANDOM pCeGenRandom = NULL; static GETSYSTEMPOWERSTATUS pGetSystemPowerStatusEx2 = NULL; FILETIME creationTime, exitTime, kernelTime, userTime; LARGE_INTEGER performanceCount; SYSTEM_POWER_STATUS_EX2 powerStatus; MEMORYSTATUS memoryStatus; HANDLE handle; POINT point; RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE ]; int length; if( krnlIsExiting() ) return; /* Initialize the native function pointers if necessary. CeGetRandom() is only available in relatively new versions of WinCE, so we have to link it dynamically */ if( pCeGenRandom == NULL ) { HANDLE hCoreDLL; if( ( hCoreDLL = GetModuleHandle( TEXT( "Coredll.dll" ) ) ) != NULL ) pCeGenRandom = ( CEGENRANDOM ) GetProcAddress( hCoreDLL, TEXT( "CeGenRandom" ) ); } if( pGetSystemPowerStatusEx2 == NULL ) { HANDLE hGetpower; if( ( hGetpower = GetModuleHandle( TEXT( "Getpower.dll" ) ) ) != NULL ) pGetSystemPowerStatusEx2 = ( GETSYSTEMPOWERSTATUS ) \ GetProcAddress( hGetpower, TEXT( "GetSystemPowerStatusEx2" ) ); } initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get various basic pieces of system information: Handle of active window, handle of window with mouse capture, handle of clipboard owner handle of start of clpboard viewer list, pseudohandle of current process, current process ID, pseudohandle of current thread, current thread ID, handle of desktop window, handle of window with keyboard focus, whether system queue has any events, cursor position for last message, 1 ms time for last message, handle of window with clipboard open, handle of process heap, handle of procs window station, types of events in input queue, and milliseconds since Windows was started */ addRandomValue( randomState, GetActiveWindow() ); addRandomValue( randomState, GetCapture() ); addRandomValue( randomState, GetCaretBlinkTime() ); addRandomValue( randomState, GetClipboardOwner() ); addRandomValue( randomState, GetCurrentProcess() ); addRandomValue( randomState, GetCurrentProcessId() ); addRandomValue( randomState, GetCurrentThread() ); addRandomValue( randomState, GetCurrentThreadId() ); addRandomValue( randomState, GetDesktopWindow() ); addRandomValue( randomState, GetDC( NULL ) ); addRandomValue( randomState, GetDoubleClickTime() ); addRandomValue( randomState, GetFocus() ); addRandomValue( randomState, GetForegroundWindow() ); addRandomValue( randomState, GetMessagePos() ); addRandomValue( randomState, GetOpenClipboardWindow() ); addRandomValue( randomState, GetProcessHeap() ); addRandomValue( randomState, GetQueueStatus( QS_ALLINPUT ) ); addRandomValue( randomState, GetTickCount() ); if( krnlIsExiting() ) return; /* Get multiword system information: Current caret position, current mouse cursor position */ GetCaretPos( &point ); addRandomData( randomState, &point, sizeof( POINT ) ); GetCursorPos( &point ); addRandomData( randomState, &point, sizeof( POINT ) ); /* Get percent of memory in use, bytes of physical memory, bytes of free physical memory, bytes in paging file, free bytes in paging file, user bytes of address space, and free user bytes */ memoryStatus.dwLength = sizeof( MEMORYSTATUS ); GlobalMemoryStatus( &memoryStatus ); addRandomData( randomState, &memoryStatus, sizeof( MEMORYSTATUS ) ); /* Get thread and process creation time, exit time, time in kernel mode, and time in user mode in 100ns intervals */ handle = GetCurrentThread(); GetThreadTimes( handle, &creationTime, &exitTime, &kernelTime, &userTime ); addRandomData( randomState, &creationTime, sizeof( FILETIME ) ); addRandomData( randomState, &exitTime, sizeof( FILETIME ) ); addRandomData( randomState, &kernelTime, sizeof( FILETIME ) ); addRandomData( randomState, &userTime, sizeof( FILETIME ) ); /* Get extended battery/power status information. We set the fUpdate flag to force a re-read of fresh data rather than a re-use of cached information */ if( pGetSystemPowerStatusEx2 != NULL && \ ( length = \ pGetSystemPowerStatusEx2( &powerStatus, sizeof( SYSTEM_POWER_STATUS_EX2 ), TRUE ) ) > 0 ) addRandomData( randomState, &powerStatus, length ); /* Get random data provided by the OS. Since this is expected to be provided by the system vendor, it's quite likely to be the usual process ID + time */ if( pCeGenRandom != NULL ) { BYTE randomBuffer[ 32 ]; if( pCeGenRandom( 32, randomBuffer ) ) addRandomData( randomState, randomBuffer, 32 ); } /* The following are fixed for the lifetime of the process so we only add them once */ if( !addedFixedItems ) { SYSTEM_INFO systemInfo; GetSystemInfo( &systemInfo ); addRandomData( randomState, &systemInfo, sizeof( SYSTEM_INFO ) ); addedFixedItems = TRUE; } /* The performance of QPC varies depending on the architecture it's running on, and is completely platform-dependant. If there's no hardware performance counter available, it uses the 1ms system timer, although usually there's some form of hardware timer available. Since there may be no correlation, or only a weak correlation, between the performance counter and the system clock, we get the time from both sources */ if( QueryPerformanceCounter( &performanceCount ) ) addRandomData( randomState, &performanceCount, sizeof( LARGE_INTEGER ) ); addRandomValue( randomState, GetTickCount() ); /* Flush any remaining data through. Quality = int( 33 1/3 % ) */ endRandomData( randomState, 34 ); }
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 ); }
void fastPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; /* BatteryTimeRec batteryTimeInfo; */ SMStatus soundStatus; ThreadID threadID; ThreadState threadState; EventRecord eventRecord; Point point; WindowPtr windowPtr; PScrapStuff scrapInfo; UnsignedWide usSinceStartup; BYTE dataBuffer[ 2 + 8 ]; /* short driverRefNum; */ UInt32 dateTime; /* int count, dummy; */ NumVersion version; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get the status of the last alert, how much battery time is remaining and the voltage from all batteries, the internal battery status, the current date and time and time since system startup in ticks, the application heap limit and current and heap zone, free memory in the current and system heap, microseconds since system startup, whether QuickDraw has finished drawing, modem status, SCSI status information, maximum block allocatable without compacting, available stack space, the last QuickDraw error code */ /* addRandomValue( randomState, GetAlertStage() ); count = BatteryCount(); while( count-- > 0 ) { addRandomValue( randomState, GetBatteryVoltage( count ) ); GetBatteryTimes( count, &batteryTimeInfo ); addRandomData( randomState, &batteryTimeInfo, sizeof( BatteryTimeRec ) ); } if( !BatteryStatus( buffer, dataBuffer + 1 ) ) addRandomValue( randomState, dataBuffer ); */ GetDateTime( &dateTime ); addRandomValue( randomState, dateTime ); addRandomValue( randomState, TickCount() ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON addRandomValue( randomState, GetApplLimit() ); addRandomValue( randomState, GetZone() ); addRandomValue( randomState, SystemZone() ); addRandomValue( randomState, FreeMem() ); addRandomValue( randomState, FreeMemSys() ); #endif /* MicroSeconds( &usSinceStartup ); addRandomData( randomState, &usSinceStartup, sizeof( UnsignedWide ) ); */ addRandomValue( randomState, QDDone( NULL ) ); /* ModemStatus( dataBuffer ); addRandomValue( randomState, dataBuffer[ 0 ] ); */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON addRandomValue( randomState, SCSIStat() ); #endif addRandomValue( randomState, MaxBlock() ); addRandomValue( randomState, StackSpace() ); addRandomValue( randomState, QDError() ); /* Get the event code and message, time, and mouse location for the next event in the event queue and the OS event queue */ if( EventAvail( everyEvent, &eventRecord ) ) addRandomData( randomState, &eventRecord, sizeof( EventRecord ) ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( OSEventAvail( everyEvent, &eventRecord ) ) addRandomData( randomState, &eventRecord, sizeof( EventRecord ) ); #endif /* Get all sorts of information such as device-specific info, grafport information, visible and clipping region, pattern, pen, text, and colour information, and other details, on the topmost window. Also get the window variant. If there's a colour table record, add the colour table as well */ if( ( windowPtr = FrontWindow() ) != NULL ) { /* CTabHandle colourHandle; */ #if !defined OPAQUE_TOOLBOX_STRUCTS || !OPAQUE_TOOLBOX_STRUCTS addRandomData( randomState, windowPtr, sizeof( GrafPort ) ); #endif addRandomValue( randomState, GetWVariant( windowPtr ) ); /* if( GetAuxWin( windowPtr, colourHandle ) ) { CTabPtr colourPtr; HLock( colourHandle ); colourPtr = *colourHandle; addRandomData( randomState, colourPtr, sizeof( ColorTable ) ); HUnlock( colourHandle ); } */ } /* Get mouse-related such as the mouse button status and mouse position, information on the window underneath the mouse */ addRandomValue( randomState, Button() ); GetMouse( &point ); addRandomData( randomState, &point, sizeof( Point ) ); FindWindow( point, &windowPtr ); #if !defined OPAQUE_TOOLBOX_STRUCTS || !OPAQUE_TOOLBOX_STRUCTS if( windowPtr != NULL ) addRandomData( randomState, windowPtr, sizeof( GrafPort ) ); #endif /* Get the size, handle, and location of the desk scrap/clipboard */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON scrapInfo = InfoScrap(); addRandomData( randomState, scrapInfo, sizeof( ScrapStuff ) ); #endif /* Get information on the current thread */ threadID = kCurrentThreadID; /*GetThreadID( &threadID ); */ GetThreadState( threadID, &threadState ); addRandomData( randomState, &threadState, sizeof( ThreadState ) ); /* Get the sound mananger status. This gets the number of allocated sound channels and the current CPU load from these channels */ SndManagerStatus( sizeof( SMStatus ), &soundStatus ); addRandomData( randomState, &soundStatus, sizeof( SMStatus ) ); /* Get the speech manager version and status */ /* version = SpeechManagerVersion(); addRandomData( randomState, &version, sizeof( NumVersion ) ); addRandomValue( randomState, SpeechBusy() ); */ /* Get the status of the serial port. This gets information on recent errors, read and write pending status, and flow control values */ /* if( !OpenDriver( "\p.AIn", &driverRefNum ) ) { SerStaRec serialStatus; SetStatus( driverRefNum, &serialStatus ); addRandomData( randomState, &serialStatus, sizeof( SerStaRec ) ); } if( !OpenDriver( "\p.AOut", &driverRefNum ) ) { SerStaRec serialStatus; SetStatus( driverRefNum, &serialStatus ); addRandomData( randomState, &serialStatus, sizeof( SerStaRec ) ); } */ /* Flush any remaining data through */ endRandomData( randomState, 10 ); }
void slowPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; ProcessSerialNumber psn; GDHandle deviceHandle; GrafPtr currPort; QElemPtr queuePtr; QHdrPtr queueHdr; static BOOLEAN addedFixedItems = FALSE; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Walk through the list of graphics devices adding information about a device (IM VI 21-21) */ deviceHandle = GetDeviceList(); while( deviceHandle != NULL ) { GDHandle currentHandle = deviceHandle; GDPtr devicePtr; HLock( ( Handle ) currentHandle ); devicePtr = *currentHandle; deviceHandle = devicePtr->gdNextGD; addRandomData( randomState, devicePtr, sizeof( GDevice ) ); HUnlock( ( Handle ) currentHandle ); } /* Walk through the list of processes adding information about each process, including the name and serial number of the process, file and resource information, memory usage information, the name of the launching process, launch time, and accumulated CPU time (IM VI 29-17) */ psn.highLongOfPSN = 0; psn.lowLongOfPSN = kNoProcess; while( !GetNextProcess( &psn ) ) { ProcessInfoRec infoRec; GetProcessInformation( &psn, &infoRec ); addRandomData( randomState, &infoRec, sizeof( ProcessInfoRec ) ); } /* Get the command type, trap address, and parameters for all commands in the file I/O queue. The parameters are quite complex and are listed on page 117 of IM IV, and include reference numbers, attributes, time stamps, length and file allocation information, finder info, and large amounts of other volume and filesystem-related data */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( ( queueHdr = GetFSQHdr() ) != NULL ) queuePtr = queueHdr->qHead; while( queuePtr != NULL ) { /* The queue entries are variant records of variable length so we need to adjust the length parameter depending on the record type */ addRandomData( randomState, queuePtr, 32 ); /* dunno how big.. */ queuePtr = queuePtr->qLink; } #endif /* The following are fixed for the lifetime of the process so we only add them once */ if( !addedFixedItems ) { Str255 appName, volName; GDHandle deviceHandle; Handle appHandle; DrvSts driveStatus; MachineLocation machineLocation; ProcessInfoRec processInfo; QHdrPtr vblQueue; SysEnvRec sysEnvirons; SysPPtr pramPtr; DefStartRec startupInfo; DefVideoRec videoInfo; DefOSRec osInfo; XPPParamBlock appleTalkParams; unsigned char *driverNames[] = { "\p.AIn", "\p.AOut", "\p.AppleCD", "\p.ATP", "\p.BIn", "\p.BOut", "\p.MPP", "\p.Print", "\p.Sony", "\p.Sound", "\p.XPP", NULL }; SInt16 count, dummy, i, node, net, vRefNum, script; SInt32 lcount, volume; /* Get the current font family ID, node ID of the local AppleMumble router, caret blink delay, CPU speed, double-click delay, sound volume, application and system heap zone, the number of resource types in the application, the number of sounds voices available, the FRef of the current resource file, volume of the sysbeep, primary line direction, computer SCSI disk mode ID, timeout before the screen is dimmed and before the computer is put to sleep, number of available threads in the thread pool, whether hard drive spin-down is disabled, the handle to the i18n resources, timeout time for the internal HDD, */ addRandomValue( randomState, GetAppFont() ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON addRandomValue( randomState, GetBridgeAddress() ); #endif addRandomValue( randomState, GetCaretTime() ); /* addRandomValue( randomState, GetCPUSpeed() ); */ addRandomValue( randomState, GetDblTime() ); GetSysBeepVolume( &volume ); addRandomValue( randomState, volume ); GetDefaultOutputVolume( &volume ); addRandomValue( randomState, volume ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON addRandomValue( randomState, ApplicationZone() ); addRandomValue( randomState, SystemZone() ); #endif addRandomValue( randomState, CountTypes() ); /* CountVoices( &count ); ** seems to crash addRandomValue( randomState, count ); */ addRandomValue( randomState, CurResFile() ); GetSysBeepVolume( &lcount ); addRandomValue( randomState, lcount ); addRandomValue( randomState, GetSysDirection() ); /* addRandomValue( randomState, GetSCSIDiskModeAddress() ); addRandomValue( randomState, GetDimmingTimeout() ); addRandomValue( randomState, GetSleepTimeout() ); */ GetFreeThreadCount( kCooperativeThread, &count ); addRandomValue( randomState, count ); /* addRandomValue( randomState, IsSpindownDisabled() ); */ addRandomValue( randomState, GetIntlResource( 0 ) ); #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON GetTimeout( &count ); addRandomValue( randomState, count ); #endif /* Get the number of documents/files which were selected when the app started and for each document get the vRefNum, name, type, and version -- OBSOLETE CountAppFiles( &dummy, &count ); addRandomValue( randomState, count ); while( count > 0 ) { AppFile theFile; GetAppFiles( count, &theFile ); addRandomData( randomState, &theFile, sizeof( AppFile ) ); count--; } */ /* Get the app's name, resource file reference number, and handle to the finder information -- OBSOLETE GetAppParams( appName, appHandle, &count ); addRandomData( randomState, appName, sizeof( Str255 ) ); addRandomValue( randomState, appHandle ); addRandomValue( randomState, count ); */ /* Get all sorts of statistics such as physical information, disk and write-protect present status, error status, and handler queue information, on floppy drives attached to the system. Also get the volume name, volume reference number and number of bytes free, for the volume in the drive */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( !DriveStatus( 1, &driveStatus ) ) addRandomData( randomState, &driveStatus, sizeof (DrvSts) ); #endif #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( !GetVInfo( 1, volName, &vRefNum, &lcount ) ) { addRandomData( randomState, volName, sizeof( Str255 ) ); addRandomValue( randomState, vRefNum ); addRandomValue( randomState, lcount ); } #endif #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( !DriveStatus( 2, &driveStatus ) ) addRandomData( randomState, &driveStatus, sizeof (DrvSts) ); #endif #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( !GetVInfo( 2, volName, &vRefNum, &lcount ) ) { addRandomData( randomState, volName, sizeof( Str255 ) ); addRandomValue( randomState, vRefNum ); addRandomValue( randomState, lcount ); } #endif /* Get information on the head and tail of the vertical retrace queue */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( ( vblQueue = GetVBLQHdr() ) != NULL ) addRandomData( randomState, vblQueue, sizeof( QHdr ) ); #endif /* Get the parameter RAM settings */ pramPtr = GetSysPPtr(); addRandomData( randomState, pramPtr, sizeof( SysParmType ) ); /* Get information about the machines geographic location */ ReadLocation( &machineLocation ); addRandomData( randomState, &machineLocation, sizeof( MachineLocation ) ); /* Get information on current graphics devices including device information such as dimensions and cursor information, and a number of handles to device-related data blocks and functions, and information about the dimentions and contents of the devices pixel image as well as the images resolution, storage format, depth, and colour usage */ deviceHandle = GetDeviceList(); do { GDPtr gdPtr; addRandomValue( randomState, deviceHandle ); HLock( ( Handle ) deviceHandle ); gdPtr = ( GDPtr ) *deviceHandle; addRandomData( randomState, gdPtr, sizeof( GDevice ) ); addRandomData( randomState, gdPtr->gdPMap, sizeof( PixMap ) ); HUnlock( ( Handle ) deviceHandle ); } while( ( deviceHandle = GetNextDevice( deviceHandle ) ) != NULL ); /* Get the current system environment, including the machine and system software type, the keyboard type, where there's a colour display attached, the AppleTalk driver version, and the VRefNum of the system folder */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON SysEnvirons( curSysEnvVers, &sysEnvirons ); addRandomData( randomState, &sysEnvirons, sizeof( SysEnvRec ) ); #endif /* Get the AppleTalk node ID and network number for this machine */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( GetNodeAddress( &node, &net ) ) { addRandomValue( randomState, node ); addRandomValue( randomState, net ); } #endif /* Get information on each device connected to the ADB including the device handler ID, the devices ADB address, and the address of the devices handler and storage area */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON count = CountADBs(); while( count-- > 0 ) { ADBDataBlock adbInfo; GetIndADB( &adbInfo, count ); addRandomData( randomState, &adbInfo, sizeof( ADBDataBlock ) ); } #endif /* Open the most common device types and get the general device status information and (if possible) device-specific status. The general device information contains the device handle and flags, I/O queue information, event information, and other driver-related details */ /* Try something like this again.. and ur a dead man, Peter ;-) -xmath */ /* for( count = 0; driverNames[ count ] != NULL; count++ ) { AuxDCEHandle dceHandle; short driverRefNum; ** Try and open the driver ** if( OpenDriver( driverNames[ count ], &driverRefNum ) ) continue; ** Get a handle to the driver control information (this could also be done with GetDCtlHandle()) ** Status( driverRefNum, 1, &dceHandle ); HLock( dceHandle ); addRandomData( randomState, *dceHandle, sizeof( AuxDCE ) ); HUnlock( dceHandle ); CloseDriver( driverRefNum ); } */ /* Get the name and volume reference number for the current volume */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON GetVol( volName, &vRefNum ); addRandomData( randomState, volName, sizeof( Str255 ) ); addRandomValue( randomState, vRefNum ); #endif /* Get the time information, attributes, directory information and bitmap, volume allocation information, volume and drive information, pointers to various pieces of volume-related information, and details on path and directory caches, for each volume */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( ( queueHdr = GetVCBQHdr() ) != NULL ) queuePtr = queueHdr->qHead; while ( queuePtr != NULL ) { addRandomData( randomState, queuePtr, sizeof( VCB ) ); queuePtr = queuePtr->qLink; } #endif /* Get the driver reference number, FS type, and media size for each drive */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON if( ( queueHdr = GetDrvQHdr() ) != NULL ) queuePtr = queueHdr->qHead; while ( queuePtr != NULL ) { addRandomData( randomState, queuePtr, sizeof( DrvQEl ) ); queuePtr = queuePtr->qLink; } #endif /* Get global script manager variables and vectors, including the globals changed count, font, script, and i18n flags, various script types, and cache information */ for( count = 0; count < 30; count++ ) addRandomValue( randomState, GetScriptManagerVariable( count ) ); /* Get the script code for the font script the i18n script, and for each one add the changed count, font, script, i18n, and display flags, resource ID's, and script file information */ script = FontScript(); addRandomValue( randomState, script ); for( count = 0; count < 30; count++ ) addRandomValue( randomState, GetScriptVariable( script, count ) ); script = IntlScript(); addRandomValue( randomState, script ); for( count = 0; count < 30; count++ ) addRandomValue( randomState, GetScriptVariable( script, count ) ); /* Get the device ID, partition, slot number, resource ID, and driver reference number for the default startup device */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON GetDefaultStartup( &startupInfo ); addRandomData( randomState, &startupInfo, sizeof( DefStartRec ) ); #endif /* Get the slot number and resource ID for the default video device */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON GetVideoDefault( &videoInfo ); addRandomData( randomState, &videoInfo, sizeof( DefVideoRec ) ); #endif /* Get the default OS type */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON GetOSDefault( &osInfo ); addRandomData( randomState, &osInfo, sizeof( DefOSRec ) ); #endif /* Get the AppleTalk command block and data size and number of sessions */ #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON ASPGetParms( &appleTalkParams, FALSE ); addRandomData( randomState, &appleTalkParams, sizeof( XPPParamBlock ) ); #endif addedFixedItems = TRUE; } /* Flush any remaining data through */ endRandomData( randomState, 100 ); }
void slowPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; key_info keyInfo; team_info teami; thread_info threadi; area_info areai; port_info porti; sem_info semi; image_info imagei; double temperature; int32 devID, cookie; int fd, value; if( ( fd = open( "/dev/urandom", O_RDONLY ) ) >= 0 ) { MESSAGE_DATA msgData; BYTE buffer[ ( DEVRANDOM_BITS / 8 ) + 8 ]; static const int quality = 100; /* Read data from /dev/urandom, which won't block (although the quality of the noise is lesser). */ read( fd, buffer, DEVRANDOM_BITS / 8 ); setMessageData( &msgData, buffer, DEVRANDOM_BITS / 8 ); krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE_S, &msgData, CRYPT_IATTRIBUTE_ENTROPY ); zeroise( buffer, DEVRANDOM_BITS / 8 ); close( fd ); krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE, ( MESSAGE_CAST ) &quality, CRYPT_IATTRIBUTE_ENTROPY_QUALITY ); return; } initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get the state of all keys on the keyboard and various other system states */ #if 0 /* See comment at start */ if( get_key_info( &keyInfo ) == B_NO_ERROR ) addRandomData( randomState, &keyInfo, sizeof( key_info ) ); #endif /* 0 */ value = is_computer_on(); /* Returns 1 if computer is on */ addRandomValue( randomState, value ); temperature = is_computer_on_fire(); /* MB temp.if on fire */ addRandomData( randomState, &temperature, sizeof( double ) ); /* Get information on all running teams (thread groups, ie applications). This returns the team ID, number of threads, images, and areas, debugger port and thread ID, program args, and uid and gid */ cookie = 0; while( get_next_team_info( &cookie, &teami ) == B_NO_ERROR ) addRandomData( randomState, &teami, sizeof( teami ) ); /* Get information on all running threads. This returns the thread ID, team ID, thread name and state (eg running, suspended, asleep, blocked), the thread priority, elapsed user and kernel time, and thread stack information */ cookie = 0; while( get_next_thread_info( 0, &cookie, &threadi ) == B_NO_ERROR ) { addRandomValue( randomState, has_data( threadi.thread ) ); addRandomData( randomState, &threadi, sizeof( threadi ) ); } /* Get information on all memory areas (chunks of virtual memory). This returns the area ID, name, size, locking scheme and protection bits, ID of the owning team, start address, number of resident bytes, copy- on-write count, an number of pages swapped in and out */ cookie = 0; while( get_next_area_info( 0, &cookie, &areai ) == B_NO_ERROR ) addRandomData( randomState, &areai, sizeof( areai ) ); /* Get information on all message ports. This returns the port ID, ID of the owning team, message queue length, number of messages in the queue, and total number of messages processed */ cookie = 0; while( get_next_port_info( 0, &cookie, &porti ) == B_NO_ERROR ) addRandomData( randomState, &porti, sizeof( porti ) ); /* Get information on all semaphores. This returns the semaphore and owning team ID, the name, thread count, and the ID of the last thread which acquired the semaphore */ cookie = 0; while( get_next_sem_info( 0, &cookie, &semi ) == B_NO_ERROR ) addRandomData( randomState, &semi, sizeof( semi ) ); /* Get information on all images (code blocks, eg applications, shared libraries, and add-on images (DLL's on steroids). This returns the image ID and type (app, library, or add-on), the order in which the image was loaded compared to other images, the address of the init and shutdown routines, the device and node where the image lives, and the image text and data sizes) */ cookie = 0; while( get_next_image_info( 0, &cookie, &imagei ) == B_NO_ERROR ) addRandomData( randomState, &imagei, sizeof( imagei ) ); /* Get information on all storage devices. This returns the device number, root inode, various device parameters such as I/O block size, and the number of free and used blocks and inodes */ devID = 0; while( next_dev( &devID ) >= 0 ) { fs_info fsInfo; if( fs_stat_dev( devID, &fsInfo ) == B_NO_ERROR ) addRandomData( randomState, &fsInfo, sizeof( fs_info ) ); } /* Flush any remaining data through */ endRandomData( randomState, 100 ); }
void slowPoll( void ) { RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE ]; cyg_handle_t hThread = 0; cyg_uint16 threadID = 0; #ifdef CYGPKG_IO_PCI cyg_pci_device_id pciDeviceID; #endif /* CYGPKG_IO_PCI */ #ifdef CYGPKG_POWER PowerController *powerControllerInfo; #endif /* CYGPKG_POWER */ int itemsAdded = 0, iterationCount; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get the thread handle, ID, state, priority, and stack usage for every thread in the system */ for( iterationCount = 0; cyg_thread_get_next( &hThread, &threadID ) && \ iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ ) { cyg_thread_info threadInfo; if( !cyg_thread_get_info( hThread, threadID, &threadInfo ) ) continue; addRandomData( randomState, &threadInfo, sizeof( cyg_thread_info ) ); itemsAdded++; } /* Walk the power-management info getting the power-management state for each device. This works a bit strangely, the power controller information is a static table created at system build time so all that we're doing is walking down an array getting one entry after another */ #ifdef CYGPKG_POWER for( powerControllerInfo = &( __POWER__[ 0 ] ), iterationCount = 0; powerControllerInfo != &( __POWER_END__ ) && \ iterationCount < FAILSAFE_ITERATIONS_MED; powerControllerInfo++, iterationCount++ ) { const PowerMode power_get_controller_mode( powerControllerInfo ); addRandomValue( randomState, PowerMode ); } #endif /* CYGPKG_POWER */ /* Add PCI device information if there's PCI support present */ #ifdef CYGPKG_IO_PCI if( cyg_pci_find_next( CYG_PCI_NULL_DEVID, &pciDeviceID ) ) { iterationCount = 0; do { cyg_pci_device pciDeviceInfo; cyg_pci_get_device_info( pciDeviceID, &pciDeviceInfo ); addRandomValue( randomState, PowerMode ); addRandomData( randomState, &pciDeviceInfo, sizeof( cyg_pci_device ) ); itemsAdded++; } while( cyg_pci_find_next( pciDeviceID, &pciDeviceID ) && \ iterationCount++ < FAILSAFE_ITERATIONS_MED ); } #endif /* CYGPKG_IO_PCI */ /* eCOS also has a CPU load-monitoring facility that we could in theory use as a source of entropy but this is really meant for performance- monitoring and isn't very suitable for use as an entropy source. The way this works is that your first call a calibration function cyg_cpuload_calibrate() and then when it you want to get load statistics call cyg_cpuload_create()/cyg_cpuload_get()/ cyg_cpuload_delete(), with get() returning the load over a 0.1s, 1s, and 10s interval. The only one of these capabilities that's even potentially usable is cyg_cpuload_calibrate() and even that's rather dubious for general use since it runs a thread at the highest priority level for 0.1s for calibration purposes and measures the elapsed tick count, which will hardly endear us to other threads in the system. It's really meant for development-mode load measurements and can't safely be used as an entropy source */ /* Flush any remaining data through and produce an estimate of its value. Unlike its use in standard OSes this isn't really a true estimate since virtually all of the entropy is coming from the seed file, all this does is complete the seed-file quality estimate to make sure that we don't fail the entropy test */ endRandomData( randomState, ( itemsAdded > 5 ) ? 20 : 0 ); }
void slowPoll( void ) { static BOOLEAN addedFixedItems = FALSE; RANDOM_STATE randomState; BYTE buffer[ RANDOM_BUFSIZE + 8 ]; struct batteryInfoType { uint16_t warnThreshold; /* Percent left for warn */ uint16_t criticalThreshold; /* Percent left for critical warn */ uint16_t shutdownThreshold; /* Percent left for shutdown */ uint32_t timeout; /* Battery timeout */ SysBatteryKind type; /* Battery type */ Boolean pluggedIn; /* Whether battery plugged in */ uint8_t powerLevel; /* Percent power remaining */ } batteryInfo; const FontType *fontPtr; MenuBarType *menuPtr; void *stackStart, *stackEnd; MemHeapInfoType memInfo; RectangleType rectangleInfo; EvtQueueHandle evtQueueHandle; DatabaseID databaseID; FontID fontID; WinHandle winHandle; WinFlagsType winFlags; PatternType pattern; uint32_t version; uint16_t formID; uint8_t value; initRandomData( randomState, buffer, RANDOM_BUFSIZE ); /* Get the handle of the current thread's event queue, current resource database ID, start and end of the current thread's stack, ID and pointer to the current font, ID and pointer to the currently active form, and pointer to the currently active menu */ evtQueueHandle = EvtGetThreadEventQueue(); addRandomValue( randomState, evtQueueHandle ); SysCurAppDatabase( &databaseID ); addRandomValue( randomState, databaseID ); SysGetStackInfo( &stackStart, &stackEnd ); addRandomData( randomState, &stackStart, sizeof( void * ) ); addRandomData( randomState, &stackEnd, sizeof( void * ) ); fontID = FntGetFont(); addRandomValue( randomState, fontID ); fontPtr = FntGetFontPtr(); addRandomData( randomState, &fontPtr, sizeof( FontType * ) ); formID = FrmGetActiveFormID(); addRandomValue( randomState, formID ); if( formID > 0 ) { FormType *formPtr; formPtr = FrmGetFormPtr( formID ); addRandomData( randomState, &formPtr, sizeof( FormType * ) ); } menuPtr = MenuGetActiveMenu(); addRandomData( randomState, &menuPtr, sizeof( MenuBarType * ) ); /* Get system memory info: heap base address, total memory, memory in use, number of chunks allocated/free and chunk memory used/free, available memory block info */ MemDynHeapGetInfo( &memInfo ); addRandomData( randomState, &memInfo, sizeof( MemHeapInfoType ) ); /* Get the handle, creation flags, and size of the active window, the screen window created at startup, and the current draw window, the size and clipping rectangle of the draw window, the current pattern type, and the current scaling mode */ winHandle = WinGetActiveWindow(); addRandomValue( randomState, winHandle ); winFlags = WinGetWindowFlags( winHandle ); addRandomValue( randomState, winFlags ); WinGetWindowFrameRect( winHandle, &rectangleInfo ); addRandomData( randomState, &rectangleInfo, sizeof( RectangleType ) ); winHandle = WinGetDisplayWindow(); addRandomValue( randomState, winHandle ); winHandle = WinGetDrawWindow(); addRandomValue( randomState, winHandle ); winFlags = WinGetWindowFlags( winHandle ); addRandomValue( randomState, winFlags ); WinGetDrawWindowBounds( &rectangleInfo ); addRandomData( randomState, &rectangleInfo, sizeof( RectangleType ) ); WinGetClip( &rectangleInfo ); addRandomData( randomState, &rectangleInfo, sizeof( RectangleType ) ); pattern = WinGetPatternType(); addRandomValue( randomState, pattern ); if( FtrGet( sysFtrCreator, sysFtrNumWinVersion, &version ) == errNone && \ version >= 5 ) { uint32_t scaleType; /* Not implemented before PalmOS 5.3, requires the 1.5x Display Feature Set to avoid generating a fatal alert */ scaleType = WinGetScalingMode(); addRandomValue( randomState, scaleType ); } /* Get expansiode card info (capability flags, manufacturer, product, and device info including unique serial number if available), and media info (disk space, partition info, pseudo-HDD metrics) for all expansion slots */ if( FtrGet( sysFileCExpansionMgr,expFtrIDVersion, &version ) == errNone ) { uint32_t slotIterator = expIteratorStart; uint16_t slotRefNum; while( slotIterator != expIteratorStop && \ ExpSlotEnumerate( &slotRefNum, &slotIterator ) == errNone ) { ExpCardInfoType cardInfo; CardMetricsType cardMetrics; addRandomValue( randomState, slotRefNum ); ExpCardInfo( slotRefNum, &cardInfo ); addRandomData( randomState, &cardInfo, sizeof( ExpCardInfoType ) ); ExpCardMetrics( slotRefNum, &cardMetrics ); addRandomData( randomState, &cardMetrics, sizeof( CardMetricsType ) ); } } /* Get attributes, filesystem type, mount info, media type, space used, and total space for all mounted volumes */ if( FtrGet( sysFileCVFSMgr, vfsFtrIDVersion, &version ) == errNone ) { uint32_t volIterator = vfsIteratorStart; uint16_t volRefNum; while( volIterator != vfsIteratorStop && \ VFSVolumeEnumerate( &volRefNum, &volIterator ) == errNone ) { VolumeInfoType volInfo; uint32_t volUsed, volTotal; addRandomValue( randomState, volRefNum ); VFSVolumeInfo( volRefNum, &volInfo ); addRandomData( randomState, &volInfo, sizeof( VolumeInfoType ) ); VFSVolumeSize( volRefNum, &volUsed, &volTotal ); addRandomValue( randomState, volUsed ); addRandomValue( randomState, volTotal ); } } /* Get battery state info */ if( SysBatteryInfo( FALSE, &batteryInfo.warnThreshold, &batteryInfo.criticalThreshold, &batteryInfo.shutdownThreshold, &batteryInfo.timeout, &batteryInfo.type, &batteryInfo.pluggedIn, &batteryInfo.powerLevel ) == errNone ) addRandomData( randomState, &batteryInfo, sizeof( struct batteryInfoType ) ); /* Get the LCD brightness and contrast level */ value = SysLCDBrightness( FALSE, 0 ); addRandomValue( randomState, value ); value = SysLCDContrast( FALSE, 0 ); addRandomValue( randomState, value ); /* The following are fixed for the lifetime of the process so we only add them once */ if( !addedFixedItems ) { struct ftrInfoType { uint32_t creator; /* Feature creator */ uint16_t number; /* Feature number */ uint32_t value; /* Feature value */ } ftrInfo; uint16_t ftrIterator, romTokenSize; uint8_t *romToken; /* Get system features. This includes a large amount of information ranging from fairly static (extensive hardware capability info, OS version/configuration data) through to variable (default font, locale, etc) */ for( ftrIterator = 0; \ FtrGetByIndex( ftrIterator, FALSE, &ftrInfo.creator, \ &ftrInfo.number, &ftrInfo.value ) == errNone; \ ftrIterator++ ) addRandomData( randomState, &ftrInfo, sizeof( struct ftrInfoType ) ); /* Get the ROM serial number. This is somewhat complex, for it to be valid the function call has to succeed and the returned pointer has to be non-null and the first byte of the returned data can't be 0xFF */ if( SysGetROMToken( sysROMTokenSnum, &romToken, \ &romTokenSize ) == errNone && \ romToken != NULL && *romToken != 0xFF ) addRandomData( randomState, &romToken, romTokenSize ); addedFixedItems = TRUE; } /* Flush any remaining data through */ endRandomData( randomState, 100 ); }