#define SystemSevenOrLater 1 /* Needed to force Gestalt to be a direct trap. */ #define USESROUTINEDESCRIPTORS 1 #include #include #include #include #include #include #include #include extern UniversalProcPtr LoadMyDataForkFragment(ProcInfoType procInfo, ConnectionID *fragID, OSErr *erroRet); extern Boolean IsSystem7(void); extern Boolean IsPowerPC(void); #define uppPSPlugInProcInfo \ (kPascalStackBased | RESULT_SIZE(kNoByteCode) | \ STACK_ROUTINE_PARAMETER(1, kTwoByteCode) | \ STACK_ROUTINE_PARAMETER(2, kFourByteCode) | \ STACK_ROUTINE_PARAMETER(3, kFourByteCode) | \ STACK_ROUTINE_PARAMETER(4, kFourByteCode)) typedef pascal void PlugInEntryProc(short, void *, long *, short *); /* Just for type checking. */ PlugInEntryProc main; typedef struct { PlugInEntryProc *entryPoint; ConnectionID connection; long plugInData; } InterposerPlugInInfo; pascal void main(short selector, void *stuff, long *data, short *result) { UniversalProcPtr routineDesc; OSErr error; InterposerPlugInInfo **saveInfo = (InterposerPlugInInfo **)data; if (!IsSystem7() || !IsPowerPC()) { /* Feel free to call a 68K routine that implements your filter instead. */ *result = 1; return; } if (*saveInfo == NULL) { ConnectionID fragID; if ((routineDesc = LoadMyDataForkFragment(uppPSPlugInProcInfo, &fragID, &error)) == NULL) { #ifdef DEBUG DebugStr("\pCouldn't load.\n"); #endif *result = error; return; } else { InterposerPlugInInfo *myInfo; if ((myInfo = (InterposerPlugInInfo *)NewPtr(sizeof(InterposerPlugInInfo))) == NULL) { *result = MemError(); return; } myInfo->entryPoint = (PlugInEntryProc *)routineDesc; myInfo->connection = fragID; myInfo->plugInData = (long)NULL; *saveInfo = myInfo; } } if (*saveInfo != NULL) ((*saveInfo)->entryPoint)(selector, stuff, &((*saveInfo)->plugInData), result); /* Unload the plug-in if we're done. This is non-optimal in that * repeated invocations of a filter require it to be reloaded each * time, but we don't pay this cost on continue calls etc. so it isn't * that bad. */ if (selector == filterSelectorFinish) { CloseConnection(&(*saveInfo)->connection); DisposePtr((Ptr)*saveInfo); *saveInfo = NULL; } } static UniversalProcPtr LoadMyDataForkFragment(ProcInfoType procInfo, ConnectionID *fragID, OSErr *errorRet) { FCBPBRec thisFileInfo; FSSpec fileSpec; ConnectionID myFragID; Ptr entryAddress; Str255 error; RoutineDescriptor *theDesc; OSErr loadError; thisFileInfo.ioNamePtr = (StringPtr)&fileSpec.name ; thisFileInfo.ioRefNum = CurResFile(); thisFileInfo.ioFCBIndx = 0; PBGetFCBInfo(&thisFileInfo, false); if (thisFileInfo.ioResult != noErr) return NULL; fileSpec.vRefNum = thisFileInfo.ioFCBVRefNum; fileSpec.parID = thisFileInfo.ioFCBParID; if ((loadError = GetDiskFragment(&fileSpec, 0, 0, NULL, kLoadLib, &myFragID, &entryAddress, &error)) != noErr) { #ifdef DEBUG DebugStr(error); #endif if (errorRet != NULL) *errorRet = loadError; return NULL; } if (fragID != NULL) *fragID = myFragID; theDesc = NewRoutineDescriptor((ProcPtr)entryAddress, procInfo, kPowerPCISA); return theDesc; } #include static Boolean IsSystem7(void) { SysEnvRec environs; return (SysEnvirons(1, &environs) == noErr && environs.systemVersion >= 0x0700); } static Boolean IsPowerPC(void) { long systemArchitecture; return (Gestalt(gestaltSysArchitecture, &systemArchitecture) == noErr && systemArchitecture == gestaltPowerPC); }