home *** CD-ROM | disk | FTP | other *** search
- /* flab.c
- * ⌐ 1992 - Michael S. Engber - All Rights Reserved
- */
-
- #include <AppleEvents.h>
- #include <Finder.h>
- #include "ierror.h"
- #include "flab.h"
-
-
- /* Looks through running processes for one with the specified type and signature.
- * Passes back the its ProcessSerialNumber & FSSpec.
- */
- static OSErr FindProcess(OSType processType, OSType processSig, ProcessSerialNumberPtr psn_p, FSSpecPtr spec_p){
- ProcessInfoRec pinfo;
- pinfo.processName = NULL;
- pinfo.processInfoLength = sizeof(pinfo);
- pinfo.processAppSpec = spec_p;
-
- psn_p->highLongOfPSN = 0;
- psn_p->lowLongOfPSN = kNoProcess;
-
- while(!GetNextProcess(psn_p)){
- if(!GetProcessInformation(psn_p,&pinfo) &&
- pinfo.processType == processType &&
- pinfo.processSignature == processSig){
- return noErr;
- }
- }
- return -1;
- }
-
- /* Sends the specified process a quit AE.
- */
- static OSErr QuitProcess(ProcessSerialNumberPtr psn_p, Boolean wait){
- OSErr err;
- AppleEvent ae;
- AppleEvent aeReply;
- AEAddressDesc aeAddr;
-
- if(err=AECreateDesc(typeProcessSerialNumber,(Ptr)psn_p,sizeof(ProcessSerialNumber),&aeAddr)) return err;
- if(err=AECreateAppleEvent(kCoreEventClass,kAEQuitApplication,&aeAddr,0,kAnyTransactionID,&ae)){
- AEDisposeDesc(&aeAddr);
- return err;
- }
- err = AESend(&ae,&aeReply,wait?kAEWaitReply:kAENoReply,kAENormalPriority,kNoTimeOut,NULL,NULL);
- AEDisposeDesc(&ae);
- AEDisposeDesc(&aeAddr);
- AEDisposeDesc(&aeReply);
- return err;
- }
-
-
- /* Passes back the Finder's ProcessSerialNumber & FSSpec. */
- static OSErr FindFinder(ProcessSerialNumberPtr psn_p, FSSpecPtr spec_p){
- return FindProcess('FNDR','MACS',psn_p,spec_p);
- }
-
- /* Passes back the File Sharing Extension's ProcessSerialNumber. */
- static OSErr FindFileShareExt(ProcessSerialNumberPtr psn_p){
- FSSpec danQuayle;
- return FindProcess('INIT','hhgg',psn_p,&danQuayle);
- }
-
-
- /* Sends the Finder a quit AE.
- * Passes back the Finder's FSSpec for re-Launching it.
- */
- static OSErr QuitFinder(FSSpecPtr finderSpec_p){
- OSErr err;
- ProcessSerialNumber finderPsn;
- ProcessSerialNumber fSharePsn;
-
- if(err=FindFinder(&finderPsn,finderSpec_p)) return err;
-
- /* find & quit the File Sharing Extension */
- if(!FindFileShareExt(&fSharePsn)){
- if(err=QuitProcess(&fSharePsn,false)) return err;
- }
-
- /* now quit the Finder */
- return QuitProcess(&finderPsn,true);
- }
-
-
- /* Launches the Finder */
- static OSErr LaunchFinder(FSSpecPtr finderSpec_p){
- LaunchParamBlockRec pb;
- pb.launchBlockID = extendedBlock;
- pb.launchEPBLength = extendedBlockLen;
- pb.launchControlFlags = launchContinue + launchNoFileFlags;
- pb.launchAppSpec = finderSpec_p;
- pb.launchAppParameters = NULL;
-
- return LaunchApplication(&pb);
- }
-
-
-
-
- static Boolean CanHackDTDB(short vRefNum){
-
- OSErr err;
- HParamBlockRec pb;
- GetVolParmsInfoBuffer vParms;
-
- pb.ioParam.ioNamePtr = NULL;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioBuffer = (Ptr)&vParms;
- pb.ioParam.ioReqCount = sizeof(vParms);
- return PBHGetVolParmsSync(&pb) == noErr &&
- ((1L<<bHasDesktopMgr) & vParms.vMAttrib) &&
- !((1L<<bHasExtFSVol) & vParms.vMAttrib);
- }
-
-
-
- static OSErr GetIconInfo (short iconType, short* rows_p, short* depth_p){
- switch(iconType){
- case kLargeIcon:
- case kLarge4BitIcon:
- case kLarge8BitIcon:
- *rows_p = 32;
- break;
- case kSmallIcon:
- case kSmall4BitIcon:
- case kSmall8BitIcon:
- *rows_p = 16;
- break;
- default:
- return -1;
- }
-
- switch(iconType){
- case kLargeIcon:
- case kSmallIcon:
- *depth_p = 1;
- break;
- case kLarge4BitIcon:
- case kSmall4BitIcon:
- *depth_p = 4;
- break;
- case kLarge8BitIcon:
- case kSmall8BitIcon:
- *depth_p = 8;
- break;
- }
- return noErr;
- }
-
- static void FlipOne(Ptr iconBuf, short iconBufSize, short rows){
- short rowBytes = iconBufSize/rows;
- Ptr topBufPtr = iconBuf;
- Ptr botBufPtr = iconBuf + iconBufSize - rowBytes;
- char rowBuf[kLarge8BitIconSize/16];
- while(botBufPtr > topBufPtr){
- BlockMove(topBufPtr,rowBuf,rowBytes);
- BlockMove(botBufPtr,topBufPtr,rowBytes);
- BlockMove(rowBuf,botBufPtr,rowBytes);
- topBufPtr += rowBytes;
- botBufPtr -= rowBytes;
- }
- }
-
- static OSErr FlipIcon(Ptr iconBuf, short iconBufSize, short iconType){
- short rows;
- short depth;
- if(GetIconInfo(iconType,&rows,&depth) == noErr){
- if(iconBufSize/(depth==1 ? 2 : 1) != rows*rows*depth/8){
- IError(iconType,"\pFlipIcon","\pbad icon info",NULL);
- return -1;
- }else{
- if(depth == 1){
- FlipOne(iconBuf,iconBufSize/2,rows);
- FlipOne(iconBuf + iconBufSize/2,iconBufSize/2,rows);
- }else{
- FlipOne(iconBuf,iconBufSize,rows);
- }
- }
- }
- return noErr;
- }
-
-
- /* Flip all icons of creator from the DTDB on the specified volume */
- static OSErr VFlipDTDB(short vRefNum, OSType creator){
- OSErr err;
- short flipCount;
- Str255 fn = "\p";
- DTPBRec pb;
- char iconBuf[kLarge8BitIconSize];
-
- /* use GetPath to fill in the DTDB's refNum */
- pb.ioNamePtr = fn;
- pb.ioVRefNum = vRefNum;
- if(err=PBDTGetPath(&pb)) return err;
-
- /* loop through & remove all creator entries */
- flipCount = 0;
- pb.ioIndex = 1;
- pb.ioFileCreator = creator;
- while(PBDTGetIconInfoSync(&pb) == noErr){
- pb.ioDTReqCount = pb.ioDTActCount;
- pb.ioDTBuffer = iconBuf;
- if(err=PBDTGetIconSync(&pb)) return err;
- if(err=FlipIcon(iconBuf,pb.ioDTActCount,pb.ioIconType)) return err;
- if(err=PBDTAddIconSync(&pb)) return err;
- ++flipCount;
- ++pb.ioIndex;
- }
-
- if(pb.ioResult != afpItemNotFound) return pb.ioResult;
-
- /* flush the DTDB if anything was flipped */
- if(flipCount > 0){
- if(err=PBDTFlushSync(&pb)) return err;
- }
- return noErr;
- }
-
- OSErr FlipBNDL(FSSpecPtr spec_p){
- OSErr err;
- FInfo info;
-
- if(err=FSpGetFInfo(spec_p,&info)) return err;
-
- if(CanHackDTDB(spec_p->vRefNum)){
- if(err=VFlipDTDB(spec_p->vRefNum,info.fdCreator)) return err;
- }
-
- return noErr;
- }
-
- OSErr RestartFinder(void){
- OSErr err;
- FSSpec finderSpec;
-
- if(err=QuitFinder(&finderSpec)) return err;
- if(err=LaunchFinder(&finderSpec)) return err;
-
- /* Wait until we're not the FrontProcess, else we may ExitToShell before the Finder
- * has fully restarted - which causes system error 41 if we are the only app running.
- * Why this is, I don't know, but this seems to solve the problem.
- *
- * Note: we launch the finder without the launchDontSwitch flag set, so it will become
- * the front process eventually (else we'd sit around looping till the user decided
- * to click somewhere and activate the Finder)
- */
- {
- Boolean svabFront = true;
- EventRecord curEvent;
- ProcessSerialNumber psn;
- ProcessSerialNumber svabPsn;
-
- if(err=GetCurrentProcess(&svabPsn)) return err;
-
- while(svabFront){
- WaitNextEvent(everyEvent,&curEvent,15L,0L);
- if(err=GetFrontProcess(&psn)) return err;
- if(err=SameProcess(&psn,&svabPsn,&svabFront)) return err;
- }
- }
- return noErr;
- }
-
-