mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-12-13 11:29:15 +00:00
267 lines
9.3 KiB
C
267 lines
9.3 KiB
C
/*
|
|
File: GestaltLookup.c
|
|
|
|
Contains: Gestalt data structure manipulation routines.
|
|
|
|
Written by: Carl C. Hewitt
|
|
|
|
Copyright: © 1988-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<SM5> 11/10/93 fau Removed ulong typedef since it's now in Types.h.
|
|
<SM4> 5/18/93 RC perfomance/bug fix changed a > to >> in FindLong
|
|
<SM3> 4/8/93 CSS Use GestaltPrivateEqu.h, and remove definitions in this file.
|
|
<11> 10/28/92 DTY Use Get/Set macros to access ExpandMem.
|
|
<10> 12/13/90 SAM Making Gestalt check for a nil proc ptr on _NewGestalt calls.
|
|
<9> 8/8/90 CCH Now only uses the stripped address during the check for function
|
|
location.
|
|
<8> 8/1/90 SAM NewGestalt now calls stripAddress with the ProcPtr passed to it
|
|
before checking to see if it is in the sys heap.
|
|
<7> 7/17/90 dba get rid of MemUtils.h
|
|
<6> 7/10/90 dba add prototypes
|
|
<5> 7/7/90 dba change routine names to match Interface.o
|
|
<4> 1/16/90 cch Fixed unitialized variable in newGestalt.
|
|
<3> 1/15/90 CCH Fixed routine to add Gestalt selectors to allow Gestalt to be
|
|
called when interrupts are off.
|
|
<2> 1/3/90 CCH Changed Gestalt equate file name.
|
|
<1> 1/2/90 CCH Changed name from Gestalt.c.
|
|
<1.9> 7/16/89 CCH Changes: (NEEDED FOR 6.0.4 AND AURORA) - Removed unnecessary
|
|
Hlocks and HUnlocks.
|
|
<1.8> 7/14/89 CCH Changes: (NEEDED FOR 6.0.4 AND AURORA AND ESPRIT) - Fixed bug in
|
|
check for gestalt function location.
|
|
<1.7> 7/10/89 CCH Changes: (NEEDED FOR AURORA) - Added check to make sure new
|
|
gestalt functions are in the sys heap.
|
|
<1.6> 5/25/89 CCH Added new parameter to getGestalt function to allow it pass back
|
|
old values when replacing codes.
|
|
<1.5> 5/18/89 CCH Several changes to Gestalt: - rewrote getGestalt in assembly and
|
|
moved to Gestalt.a - changed prefix to Gestalt equates to
|
|
"gestalt" - changed to new error codes
|
|
<1.4> 4/16/89 CCH Changed equates to new naming convention.
|
|
<1.3> 4/13/89 CCH Gestalt now passes through the return values of function code
|
|
routines.
|
|
<1.2> 3/30/89 CCH Optimized everything.
|
|
<1.1> 3/2/89 CCH Moved init code to GestaltInit.c, and cleaned up some stuff.
|
|
<1.0> 2/21/89 CCH Adding to EASE for the first time.
|
|
*/
|
|
|
|
/*********************************************************************************
|
|
*
|
|
* File: Gestalt.c
|
|
*
|
|
* Data structure access routines for Gestalt.
|
|
*
|
|
* By Carl C. Hewitt
|
|
* November 30th, 1988
|
|
*
|
|
* © Copyright 1988-1989 Apple Computer, Inc.
|
|
*
|
|
*********************************************************************************/
|
|
#include <SysEqu.h>
|
|
#include <Types.h>
|
|
#include <Memory.h>
|
|
#include <Errors.h>
|
|
#include <ExpandMemPriv.h>
|
|
#include <GestaltEqu.h>
|
|
#include <GestaltPrivateEqu.h>
|
|
|
|
/************************
|
|
* types local to this file
|
|
************************/
|
|
|
|
typedef ulong LongEntry[2]; /* long entry */
|
|
typedef LongEntry *LongEntryPtr; /* ptr to a long entry */
|
|
typedef ulong (*FuncPtr)(); /* ptr to a function that returns a long */
|
|
|
|
#define GestaltPtr ((GestaltGlobalsPtr) (GetExpandMemGestalt()))
|
|
|
|
/************************
|
|
* prototypes
|
|
************************/
|
|
OSErr newGestalt(ulong replace, ulong selector, ulong value, ulong *oldProc);
|
|
OSErr removeLong(ulong selector, ulong* oldValue);
|
|
OSErr findLong(ulong selector, int* index);
|
|
|
|
|
|
/*********************************************************************************
|
|
* function: newGestalt(replace, selector, value, oldProc)
|
|
* ulong selector;
|
|
* ulong value;
|
|
* int replace;
|
|
* ulong *oldProc;
|
|
* purpose: adds the specified long into the table as entry #selector, or changes
|
|
* it if it already exists. replace determines whether this is an add or
|
|
* replace function. true means replace, false means add
|
|
*
|
|
* Replace Exists Error Action
|
|
* ——————— —————— ————— ——————
|
|
* false false no add
|
|
* false true yes -
|
|
* true false yes -
|
|
* true true no replace
|
|
*
|
|
* lastmod: 1/15/90
|
|
*********************************************************************************/
|
|
OSErr
|
|
newGestalt(ulong replace, ulong selector, ulong value, ulong *oldProc)
|
|
{
|
|
LongEntryPtr tablePtr;
|
|
Handle tempTable, myHandle;
|
|
int i, index, found;
|
|
ulong *destPtr, *srcPtr, size, strippedVal;
|
|
OSErr myResult;
|
|
|
|
if (!(value) || (value & 1)) /* proc ptr must be even */
|
|
return(paramErr);
|
|
|
|
/** Make sure the gestalt function is in the System Heap <1.7> **/
|
|
|
|
strippedVal = StripAddress((Ptr)value); /* gotta lose them high bits... <8><9> */
|
|
if ((strippedVal > **(ulong**)SysZone) && (strippedVal < StripAddress(*(Ptr*)ROMBase)))
|
|
return(gestaltLocationErr);
|
|
|
|
/** Make a new table to make our changes to so we can use Gestalt from **/
|
|
/** interrupt routines **/
|
|
|
|
size = GetHandleSize( GestaltPtr->tableH ); /* get the size of the table */
|
|
tempTable = NewHandleSysClear( size );
|
|
if (*(short*)MemErr) /* was there a problem? */
|
|
return(memFullErr);
|
|
destPtr = (ulong*) *tempTable; /* get a pointer to the new table */
|
|
srcPtr = (ulong*) *GestaltPtr->tableH; /* get a pointer to the orginal one */
|
|
for (i=0; i<size; i+=4) /* copy the original to the new */
|
|
*destPtr++ = *srcPtr++;
|
|
|
|
/** The selector has been validated by here, now find where the entry should **/
|
|
/** be in the table, whether it exists or not, and is the add or change valid? **/
|
|
|
|
myResult = noErr; /* assume we find no errors */
|
|
found = true; /* assume it's in the table */
|
|
if (!findLong(selector, &index))
|
|
{
|
|
if (replace) /* trying to _change_ nonexistant selector? */
|
|
myResult = gestaltUndefSelectorErr;
|
|
else
|
|
{
|
|
SetHandleSize(tempTable, (GestaltPtr->slotsUsed + 1) * sizeof(LongEntry));
|
|
if (*(short*)MemErr) /* was there a problem? */
|
|
myResult = memFullErr;
|
|
else
|
|
found = false;
|
|
}
|
|
}
|
|
else
|
|
if (!replace) /* trying to add an existing selector? */
|
|
myResult = gestaltDupSelectorErr;
|
|
|
|
if (myResult != noErr) /* any errors? */
|
|
{
|
|
DisposHandle(tempTable); /* get rid of our temporary table */
|
|
return(myResult);
|
|
}
|
|
|
|
/** index now contains the index that the entry should be put in at, **/
|
|
/** so increase the table size by one entry, and shift everything above **/
|
|
/** index up by one entry. **/
|
|
|
|
tablePtr = (LongEntryPtr) *tempTable;
|
|
if (!found) /* if not in table, add it */
|
|
{
|
|
for (i=GestaltPtr->slotsUsed; i > index; i--) /* shift entries up by one */
|
|
{
|
|
tablePtr[i][0] = tablePtr[i-1][0];
|
|
tablePtr[i][1] = tablePtr[i-1][1];
|
|
}
|
|
GestaltPtr->slotsUsed++; /* there is now one more entry */
|
|
tablePtr[index][0] = selector; /* add the entry information */
|
|
}
|
|
if (replace) /* if replacing, save old value */
|
|
*oldProc = tablePtr[index][1];
|
|
tablePtr[index][1] = value; /* associate this value with the selector */
|
|
|
|
/** Swap the tables that are used during a lookup. **/
|
|
|
|
myHandle = GestaltPtr->tableH;
|
|
GestaltPtr->tableH = tempTable;
|
|
DisposHandle(myHandle);
|
|
|
|
return(noErr);
|
|
} /*newGestalt*/
|
|
|
|
|
|
/*********************************************************************************
|
|
* function: removeLong(selector, oldValue)
|
|
* ulong selector;
|
|
* ulong *oldValue;
|
|
* purpose: removes the specified long from the table, and returns the old
|
|
* value.
|
|
* lastmod: 7/15/89
|
|
*********************************************************************************/
|
|
OSErr
|
|
removeLong(ulong selector, ulong* oldValue)
|
|
{
|
|
int index, i;
|
|
LongEntryPtr tablePtr;
|
|
|
|
if (!findLong(selector, &index)) /* the selector has to exist to delete it! */
|
|
return(gestaltUndefSelectorErr);
|
|
|
|
/** index now contains the index of the entry should be deleted **/
|
|
/** so decrease the table size by one entry, and shift everything above **/
|
|
/** index down by one entry. **/
|
|
|
|
tablePtr = (LongEntryPtr) *GestaltPtr->tableH;
|
|
*oldValue = tablePtr[index][1]; /* get the old value */
|
|
for (i=index; i < (GestaltPtr->slotsUsed-1); i++) { /* shift entries down by one */
|
|
tablePtr[i][0] = tablePtr[i+1][0];
|
|
tablePtr[i][1] = tablePtr[i+1][1];
|
|
} /*for*/
|
|
GestaltPtr->slotsUsed--; /* there is now one less entry */
|
|
|
|
SetHandleSize(GestaltPtr->tableH, GestaltPtr->slotsUsed * sizeof(LongEntry));
|
|
|
|
return(noErr);
|
|
} /*removeLong*/
|
|
|
|
|
|
/*********************************************************************************
|
|
* function: findLong(selector, index)
|
|
* ulong selector;
|
|
* int *index;
|
|
* purpose: returns true if the specified entry is in the table, false other-
|
|
* wise. If true is returned, index contains the index of the entry,
|
|
* otherwise, index will contain the index where the entry should be
|
|
* added.
|
|
* lastmod: 7/15/89
|
|
*********************************************************************************/
|
|
OSErr
|
|
findLong(ulong selector, int* index)
|
|
{
|
|
int i, min, max;
|
|
LongEntryPtr tablePtr;
|
|
|
|
tablePtr = (LongEntryPtr) *GestaltPtr->tableH;
|
|
|
|
/** do a binary search on the table for the selector **/
|
|
|
|
min = 0;
|
|
max = GestaltPtr->slotsUsed-1;
|
|
do {
|
|
i = min + ((max - min) >> 1); /* get middle of range */
|
|
if (tablePtr[i][0] > selector) /* are we too high? (is that possible?) */
|
|
max = i;
|
|
else if (tablePtr[i][0] < selector) /* are we too low? */
|
|
min = i+1;
|
|
else {
|
|
*index = i; /* we got it! */
|
|
return(true);
|
|
}
|
|
} while (max != min); /* until we know it's not there */
|
|
*index = min;
|
|
|
|
return(false);
|
|
} /*findLong*/
|
|
|
|
|
|
|