Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
SafeNameRegistry.c
/* |
File: SafeNameRegistry.c |
Contains: Stub routines for name registry calls |
Written by: G. Poon |
Copyright: © 1998 by Apple Computer, Inc., all rights reserved. |
Change History: |
25 Mar 98 gp Added calls to create and remove name registry proc ptrs |
18 Mar 98 gp Created |
To Do: |
*/ |
#ifndef __CODEFRAGMENTS__ |
#include <CodeFragments.h> |
#endif |
#ifndef __MIXEDMODE__ |
#include <MixedMode.h> |
#endif |
#ifndef __GESTALT__ |
#include <Gestalt.h> |
#endif |
#ifndef __ERRORS__ |
#include <Errors.h> |
#endif |
#ifndef __DIALOGS__ |
#include <Dialogs.h> |
#endif |
#ifndef __SafeNameRegistry__ |
#include "SafeNameRegistry.h" |
#endif |
/****************************************************************************** |
Prototypes |
******************************************************************************/ |
// prototypes used to find address of routine in name registry library |
OSErr Find_Symbol(Ptr* pSymAddr, Str255 pSymName, ProcInfoType pProcInfo); |
pascal OSErr GetSystemArchitecture(OSType *archType); |
/****************************************************************************** |
Typedefs |
******************************************************************************/ |
// proc typedefs for calling routines in the name registry library |
typedef pascal OSStatus (*RegistryEntryIDInitProcPtr) ( RegEntryID* id ); |
typedef pascal OSStatus (*RegistryCStrEntryLookupProcPtr) ( RegEntryID* searchPointID, |
RegCStrPathName* pathName, RegEntryID*foundEntry ); |
typedef pascal OSStatus (*RegistryEntryIterateCreateProcPtr) ( RegEntryIter* cookie ); |
typedef pascal OSStatus (*RegistryEntryIterateDisposeProcPtr) ( RegEntryIter* cookie ); |
typedef pascal OSStatus (*RegistryEntryIterateSetProcPtr) ( RegEntryIter* cookie, RegEntryID *startEntryID ); |
typedef pascal OSStatus (*RegistryEntryIterateProcPtr) ( RegEntryIter *cookie, |
RegEntryIterationOp relationship, RegEntryID *foundEntry, Boolean *done ); |
typedef pascal OSStatus (*RegistryEntryIDDisposeProcPtr) ( RegEntryID* id ); |
typedef pascal OSStatus (*RegistryPropertyGetProcPtr) ( RegEntryID *entryID, |
RegPropertyName *propertyName, void *propertyValue, RegPropertyValueSize *propertySize ); |
/****************************************************************************** |
Constants |
******************************************************************************/ |
#define kNoNameRegistryAlert 3000 |
// stack descriptors used in the name registry stub calls to pass params |
// to the proper routine in the name registry shared library |
enum { |
kRegistryEntryIDInitProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*))) |
}; |
enum { |
kRegistryCStrEntryLookupProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*))) |
| STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegCStrPathName*))) |
| STACK_ROUTINE_PARAMETER( 3, SIZE_CODE(sizeof( RegEntryID*))) |
}; |
enum { |
kRegistryEntryIterateCreateProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*))) |
}; |
enum { |
kRegistryEntryIterateDisposeProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*))) |
}; |
enum { |
kRegistryEntryIterateSetProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*))) |
| STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegEntryID*))) |
}; |
enum { |
kRegistryEntryIterateProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*))) |
| STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegEntryIterationOp))) |
| STACK_ROUTINE_PARAMETER( 3, SIZE_CODE(sizeof( RegEntryID*))) |
| STACK_ROUTINE_PARAMETER( 4, SIZE_CODE(sizeof( Boolean*))) |
}; |
enum { |
kRegistryEntryIDDisposeProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*))) |
}; |
enum { |
kRegistryPropertyGetProcInfo = kPascalStackBased |
| RESULT_SIZE( SIZE_CODE(sizeof(OSStatus))) |
| STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*))) |
| STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegPropertyName*))) |
| STACK_ROUTINE_PARAMETER( 3, SIZE_CODE(sizeof( void*))) |
| STACK_ROUTINE_PARAMETER( 4, SIZE_CODE(sizeof( RegPropertyValueSize*))) |
}; |
typedef struct |
{ |
// address of name registry routines |
ProcPtr RegistryEntryIDInitAddr; |
ProcPtr RegistryCStrEntryLookupAddr; |
ProcPtr RegistryEntryIterateCreateAddr; |
ProcPtr RegistryEntryIterateDisposeAddr; |
ProcPtr RegistryEntryIterateSetAddr; |
ProcPtr RegistryEntryIterateAddr; |
ProcPtr RegistryEntryIDDisposeAddr; |
ProcPtr RegistryPropertyGetAddr; |
Boolean hasNameRegistry; // does this cpu have a name registry |
Boolean checkedForNameRegistry; // did we check for the name registry already |
short numberOfPrinters; // total number of printers listed |
short numberOfUSBPrinters; // total number of USB printers |
short numberOfPorts; // total number of serial ports on this cpu |
Boolean supportsSerial; // do we support serial |
Boolean supportsUSB; // do we support USB |
// holds index into our STR# rsrc (name registry model path) for each entry in the printer list |
short* modelIndex; |
} USBGlobals; |
USBGlobals gGlobals; |
/*-----------------------------------------------------------------------------* |
NameRegistryInstalled |
Desc: Test to see if the name registry exists on this machine |
In: None |
Out: True if name registry exists else false |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
Boolean NameRegistryInstalled( void ) |
{ |
OSErr err=noErr; // result from gestalt call |
long result; |
// if not our first time then return previous result |
if( gGlobals.checkedForNameRegistry == true ) |
return gGlobals.hasNameRegistry; |
else { |
// check to see if name registry exists |
err = Gestalt(gestaltNameRegistryVersion, &result); |
if( err == noErr ) |
gGlobals.hasNameRegistry = true; |
else { |
gGlobals.hasNameRegistry = false; |
// put up alert if it isn't installed |
StopAlert(kNoNameRegistryAlert, nil); |
} |
gGlobals.checkedForNameRegistry=true; |
} |
return gGlobals.hasNameRegistry; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryEntryIDInit |
Desc: Stub code for name registry routine 'RegistryEntryIDInit' |
In: id - pointer to a RegEntryID to initialize |
Out: returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryEntryIDInit(RegEntryID *id) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryEntryIDInitAddr != (Ptr) nil ) |
anErr = ((RegistryEntryIDInitProcPtr) gGlobals.RegistryEntryIDInitAddr) (id); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryCStrEntryLookup |
Desc: Stub code for name registry routine 'RegistryCStrEntryLookup' |
In: searchPointID - the RegEntryID to start searching from |
pathName - the cstring path of the entry to find |
foundEntry - where to store the found entry |
Out: foundEntry - the RegEntryID of any found entry |
returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryCStrEntryLookup( RegEntryID *searchPointID, RegCStrPathName *pathName, RegEntryID *foundEntry) |
{ |
OSStatus anErr=-1; // return value |
// now call it |
if( (Ptr) gGlobals.RegistryCStrEntryLookupAddr != (Ptr) nil ) |
anErr = ((RegistryCStrEntryLookupProcPtr) gGlobals.RegistryCStrEntryLookupAddr) (searchPointID, pathName, foundEntry); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryEntryIterateCreate |
Desc: Stub code for name registry routine 'RegistryEntryIterateCreate' |
In: id - pointer to a RegEntryIter to initialize |
Out: returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryEntryIterateCreate(RegEntryIter *cookie) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryEntryIterateCreateAddr != (Ptr) nil ) |
anErr = ((RegistryEntryIterateCreateProcPtr) gGlobals.RegistryEntryIterateCreateAddr) (cookie); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryEntryIterateDispose |
Desc: Stub code for name registry routine 'RegistryEntryIterateDispose' |
In: cookie - iterator to dispose |
Out: returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryEntryIterateDispose(RegEntryIter *cookie) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryEntryIterateDisposeAddr != (Ptr) nil ) |
anErr = ((RegistryEntryIterateDisposeProcPtr) gGlobals.RegistryEntryIterateDisposeAddr) (cookie); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryEntryIterateSet |
Desc: Stub code for name registry routine 'RegistryEntryIterateSet' |
In: cookie - pointer to iterator to set |
startEntryID - name registry entry to start iterating from |
Out: returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryEntryIterateSet(RegEntryIter *cookie, RegEntryID *startEntryID) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryEntryIterateSetAddr != (Ptr) nil ) |
anErr = ((RegistryEntryIterateSetProcPtr) gGlobals.RegistryEntryIterateSetAddr) (cookie, startEntryID); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryEntryIterate |
Desc: Stub code for name registry routine 'RegistryEntryIterate' |
In: cookie - iterator to use |
relationship - direction to iterate |
foundEntry - where to store next name entry found |
done - tells if we're done with iteration |
Out: foundEntry - RegEntryID of name entry found |
done - true if no more entries found |
returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryEntryIterate(RegEntryIter *cookie, RegEntryIterationOp relationship, |
RegEntryID *foundEntry, Boolean *done) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryEntryIterateAddr != (Ptr) nil ) |
anErr = ((RegistryEntryIterateProcPtr) gGlobals.RegistryEntryIterateAddr) (cookie, relationship, foundEntry, done); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryEntryIDDispose |
Desc: Stub code for name registry routine 'RegistryEntryIDDispose' |
In: id - RegEntryID to dispose |
Out: returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryEntryIDDispose(RegEntryID *id) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryEntryIDDisposeAddr != (Ptr) nil ) |
anErr = ((RegistryEntryIDDisposeProcPtr) gGlobals.RegistryEntryIDDisposeAddr) (id); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
SafeRegistryPropertyGet |
Desc: Stub code for name registry routine 'RegistryPropertyGet' |
In: entryID - RegEntryID value that identifies a name entry |
propertyName - name of the property |
propertyValue - buffer to hold the property |
propertySize - size of the property buffer |
Out: propertySize - size of the property retrieved |
returns any errors which may have occur |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSStatus SafeRegistryPropertyGet( RegEntryID *entryID, RegPropertyName *propertyName, |
void *propertyValue, RegPropertyValueSize *propertySize) |
{ |
OSStatus anErr=-1; // return value |
if( (Ptr) gGlobals.RegistryPropertyGetAddr != (Ptr) nil ) |
anErr = ((RegistryPropertyGetProcPtr) gGlobals.RegistryPropertyGetAddr) (entryID, propertyName, propertyValue, propertySize); |
return anErr; |
} |
/*-----------------------------------------------------------------------------* |
GetSystemArchitecture |
Desc: Taken from |
DTS Technote 1077 "Calling CFM Code from Classic 68K Code". |
Returns architect of current cpu during runtime. |
In: archType - address of variable to hold architect type |
Out: archType - returns architect of current cpu pointed by this variable |
Also returns any errors |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
pascal OSErr GetSystemArchitecture(OSType *archType) |
{ |
long sSysArchitecture = 0; // static so we only Gestalt once. |
OSErr tOSErr = noErr; |
*archType = kAnyCFragArch; // assume wild architecture |
// If we don't know the system architecture yet... |
if (sSysArchitecture == 0) |
// ...Ask Gestalt what kind of machine we are running on. |
tOSErr = Gestalt(gestaltSysArchitecture, &sSysArchitecture); |
if (tOSErr == noErr) // if no errors |
{ |
if (sSysArchitecture == gestalt68k) // 68k? |
*archType = kMotorola68KCFragArch; |
else if (sSysArchitecture == gestaltPowerPC) // PPC? |
*archType = kPowerPCCFragArch; |
else |
tOSErr = gestaltUnknownErr; // who knows what might be next? |
} |
return tOSErr; |
} |
/*-----------------------------------------------------------------------------* |
Find_Symbol |
Desc: Taken from |
DTS Technote 1077 "Calling CFM Code from Classic 68K Code". |
Returns the address of a routine in a shared library |
In: pSymAddr - address of variable to hold returned address |
pSymName - a pstring of the name of the routine |
pProcInfo - stack descriptor for the routine |
Out: pSymAddr - the address of the routine pointed by this variable |
Also returns any errors |
History: |
18 Mar 98 gp Added. |
*-----------------------------------------------------------------------------*/ |
OSErr Find_Symbol(Ptr* pSymAddr, Str255 pSymName, ProcInfoType pProcInfo) |
{ |
CFragConnectionID sCID = 0; |
OSType sArchType = kAnyCFragArch; |
OSErr sOSErr = noErr; |
Str255 errMessage; |
Ptr mainAddr; |
CFragSymbolClass symClass; |
ISAType tISAType; |
ProcInfoType used = pProcInfo; // compiler warning |
if( NameRegistryInstalled() == false ) |
return -1; // return general error - gp |
if (sArchType == kAnyCFragArch) // if architecture is undefined... |
{ |
sCID = 0; // ...force (re)connect to library |
sOSErr = GetSystemArchitecture(&sArchType); // determine architecture |
if (sOSErr != noErr) |
return sOSErr; // OOPS! |
} |
if (sArchType == kMotorola68KCFragArch) // ...for CFM68K |
tISAType = kM68kISA | kCFM68kRTA; |
else if (sArchType == kPowerPCCFragArch) // ...for PPC CFM |
tISAType = kPowerPCISA | kPowerPCRTA; |
else |
sOSErr = gestaltUnknownErr; // who knows what might be next? |
if (sCID == 0) // If we haven't connected to the library yet... |
{ |
// NOTE: The library name is hard coded here. |
// I try to isolate the glue code, one file per library. |
// I have had developers pass in the Library name to allow |
// plug-in type support. Additional code has to be added to |
// each entry points glue routine to support multiple or |
// switching connection IDs. |
sOSErr = GetSharedLibrary("\pNameRegistryLib", sArchType, kLoadCFrag, |
&sCID, &mainAddr, errMessage); |
if (sOSErr != noErr) |
return sOSErr; // OOPS! |
} |
// If we haven't looked up this symbol yet... |
if ((Ptr) *pSymAddr == (Ptr) kUnresolvedCFragSymbolAddress) |
{ |
// ...look it up now |
sOSErr = FindSymbol(sCID,pSymName,pSymAddr,&symClass); |
if (sOSErr != noErr) {// in case of error... |
// ...clear the procedure pointer |
*(Ptr*) &pSymAddr = (Ptr) kUnresolvedCFragSymbolAddress; |
} |
#if !GENERATINGCFM // if this is classic 68k code... |
*pSymAddr = (Ptr)NewRoutineDescriptorTrap((ProcPtr) *pSymAddr, |
pProcInfo, tISAType); // ...create a routine descriptor... |
#endif |
} |
return sOSErr; |
} |
/*-----------------------------------------------------------------------------* |
InitNameRegistryPtrs |
Desc: Create all the proc ptrs to Name Registry calls we will |
need |
In: None |
Out: None |
History: |
25 Mar 98 gp Created |
*-----------------------------------------------------------------------------*/ |
void InitNameRegistryPtrs( void ) |
{ |
OSStatus anErr=noErr; // error code for Find_Symbol and name registry call |
if( NameRegistryInstalled() == true) { |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryEntryIDInitAddr, |
"\pRegistryEntryIDInit", kRegistryEntryIDInitProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryCStrEntryLookupAddr, |
"\pRegistryCStrEntryLookup", kRegistryCStrEntryLookupProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryEntryIterateCreateAddr, |
"\pRegistryEntryIterateCreate", kRegistryEntryIterateCreateProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryEntryIterateDisposeAddr, |
"\pRegistryEntryIterateDispose", kRegistryEntryIterateDisposeProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryEntryIterateSetAddr, |
"\pRegistryEntryIterateSet", kRegistryEntryIterateSetProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryEntryIterateAddr, |
"\pRegistryEntryIterate", kRegistryEntryIterateProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryEntryIDDisposeAddr, |
"\pRegistryEntryIDDispose", kRegistryEntryIDDisposeProcInfo ); |
anErr = Find_Symbol( (Ptr*) &gGlobals.RegistryPropertyGetAddr, |
"\pRegistryPropertyGet", kRegistryPropertyGetProcInfo ); |
} |
} |
/*-----------------------------------------------------------------------------* |
RemoveNameRegistryPtrs |
Desc: Remove all the proc ptrs we created for Name Registry calls |
In: None |
Out: None |
History: |
25 Mar 98 gp Created |
*-----------------------------------------------------------------------------*/ |
void RemoveNameRegistryPtrs(void) |
{ |
// dispose of proc ptrs |
if( gGlobals.RegistryEntryIDInitAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryEntryIDInitAddr); |
if( gGlobals.RegistryCStrEntryLookupAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryCStrEntryLookupAddr); |
if( gGlobals.RegistryEntryIterateCreateAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryEntryIterateCreateAddr); |
if( gGlobals.RegistryEntryIterateDisposeAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryEntryIterateDisposeAddr); |
if( gGlobals.RegistryEntryIterateSetAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryEntryIterateSetAddr); |
if( gGlobals.RegistryEntryIterateAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryEntryIterateAddr); |
if( gGlobals.RegistryEntryIDDisposeAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryEntryIDDisposeAddr); |
if( gGlobals.RegistryPropertyGetAddr != nil ) |
DisposeRoutineDescriptor( (struct RoutineDescriptor *) gGlobals.RegistryPropertyGetAddr); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-26