📄 mac.c
字号:
/****************************************************************************
* *
* Macintosh Randomness-Gathering Code *
* Copyright Peter Gutmann and Matthijs van Duin 1997-2002 *
* *
****************************************************************************/
/* This module is part of the cryptlib continuously seeded pseudorandom
number generator. For usage conditions, see random.c */
/* Mac threads are cooperatively scheduled (so they're what Win32 calls
fibers rather than true threads) and there isn't any real equivalent of a
mutex (only critical sections which prevent any other thread from being
scheduled, which defeats the point of multithreading), so we don't support
this pseudo-threading for randomness polling. If proper threading were
available, we'd use NewThread()/DisposeThread() to create/destroy the
background randomness-polling thread */
/* General includes */
#include <stdlib.h>
#include <string.h>
#include "crypt.h"
/* OS-specific includes */
/* Filled in by Matthijs van Duin */
#include <Power.h>
#include <Sound.h>
#include <Threads.h>
#include <Events.h>
#include <Scrap.h>
#include <MacTypes.h>
#include <Serial.h>
#include <Processes.h>
#include <Devices.h>
#include <Disks.h>
#include <OSUtils.h>
#include <Start.h>
#include <AppleTalk.h>
#include <DeskBus.h>
#include <Retrace.h>
#include <SCSI.h>
#include <SpeechSynthesis.h>
#include <Resources.h>
#include <Script.h>
#if defined __MWERKS__
#pragma mpwc_relax off
#pragma extended_errorcheck on
#endif
/* The size of the intermediate buffer used to accumulate polled data */
#define RANDOM_BUFSIZE 4096
void fastPoll( void )
{
RANDOM_STATE randomState;
BYTE buffer[ RANDOM_BUFSIZE ];
/* BatteryTimeRec batteryTimeInfo;
*/ SMStatus soundStatus;
ThreadID threadID;
ThreadState threadState;
EventRecord eventRecord;
Point point;
WindowPtr windowPtr;
PScrapStuff scrapInfo;
UnsignedWide usSinceStartup;
BYTE dataBuffer[ 2 ];
short driverRefNum;
UInt32 dateTime;
int count, dummy, bufIndex = 0;
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 ];
ProcessSerialNumber psn;
GDHandle deviceHandle;
GrafPtr currPort;
QElemPtr queuePtr;
QHdrPtr queueHdr;
static BOOLEAN addedFixedItems = FALSE;
int bufIndex = 0;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -