jyp@wucs1.wustl.edu (Jerome Yvon Plun) (06/18/91)
I am trying to use PBCatSearch to find an application based on its type ('APPL') and creator. I set ioSearchBits to fsSBFlFndrInfo, create an appropriate Finder Info record to put in ioSearchInfo1.ioFlFndrInfo and create another Finder Info record that I stuff with 0's except for the fields fsType and fsCreator (both set to all 1's) to use as a mask with ioSearchInfo2.ioFlFndrInfo. But PBCatSearch seems to return with the first application it finds. If I use the same setup but search based on the full name of the application, PBCatSearch finds it correctly (and quickly too!). Can someone clarify what Apple means by "using fields to hold masks that specify which bits are relevant" (last paragraph p 25-20)? Thanks. Jerome Jerome Plun [] Is it a crime to want something else? jyp@wucs1.wustl.edu [] Is it a crime to believe in something different? Washington University [] St Louis, MO [] "Smalltown England", New Model Army, Vengeance
casseres@apple.com (David Casseres) (06/22/91)
In article <1991Jun18.032741.24056@cec1.wustl.edu>, jyp@wucs1.wustl.edu (Jerome Yvon Plun) writes: > > I am trying to use PBCatSearch to find an application based on its type > ('APPL') and creator. I set ioSearchBits to fsSBFlFndrInfo, create an > appropriate Finder Info record to put in ioSearchInfo1.ioFlFndrInfo and > create another Finder Info record that I stuff with 0's except for the > fields fsType and fsCreator (both set to all 1's) to use as a mask with > ioSearchInfo2.ioFlFndrInfo. > But PBCatSearch seems to return with the first application it finds. I found the documentation a bit confusing, so maybe it will be worthwhile to post the C++ code I finally wound up with after some trial and error, and which works. I make no claims as to elegance, performance, etc. (If you know C but not C++, don't let it scare you.) The Scan_Volume function scans a specified volume for unlocked files with type myFavoriteType and creator myFavoriteCreator. It makes repeated calls to PBCatSearch until eofErr is returned to indicate the volume has been exhausted; each call is limited to 10 hits and to 10 milliseconds. After each call something (not shown) is done with the information returned by PBCatSearch. Also, before and after each PBCatSearch call it calls the CheckCancel function (not shown) which calls the main event loop so that the system response will not be frozen while the scan is in progress. CheckCancel returns true if the user does something that should cause the scan to be canceled (such as quitting the application). Boolean Sniffer7::Scan_Volume (short volRefNum) { OSErr err; short ix; Boolean doneWithVol = false; //Number of matches requested on each pass short const kMaxMatches = 10; //Array of matches from current pass FSSpec theResults[kMaxMatches]; //Scratch buffer for PBCatSearch long const kBufferSize = 1000; Handle hBuffer = NewHandle(kBufferSize); //Param block for PBCatSearch CSParamPtr catSearchPB = (CSParamPtr)NewPtrClear(sizeof(CSParam)); //PBCatSearch weirdness: a CInfo block to contain (the way we're //doing things) the values we want to match CInfoPBPtr spec1 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec)); //More PBCatSearch weirdness: a 2nd param block to mask the parts //of the 1st CInfo block that we consider significant CInfoPBPtr spec2 = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec)); while ((!doneWithVol) && (!CheckCancel())) { //Every time, make sure the necessary fields are re-inited. catSearchPB->ioCompletion = nil; catSearchPB->ioNamePtr = nil; catSearchPB->ioVRefNum = volRefNum; catSearchPB->ioMatchPtr = theResults; catSearchPB->ioReqMatchCount = kMaxMatches; catSearchPB->ioActMatchCount = 0; catSearchPB->ioSearchBits = fsSBFlAttrib + fsSBFlFndrInfo; catSearchPB->ioSearchInfo1 = spec1; catSearchPB->ioSearchInfo2 = spec2; catSearchPB->ioSearchTime = 100; //10 ms HLock(hBuffer); catSearchPB->ioOptBuffer = *hBuffer; catSearchPB->ioOptBufSize = kBufferSize; spec1->hFileInfo.ioFlAttrib = 0x00; //no locked files or dirs spec1->hFileInfo.ioFlFndrInfo.fdType = myFavoriteType; spec1->hFileInfo.ioFlFndrInfo.fdCreator = myFavoriteCreator; spec2->hFileInfo.ioFlAttrib = 0x11; //bits 0 & 4 spec2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF; //all bits of this field spec2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF; //all bits of this field //Call PBCatSearch. It returns eofErr when it has finished the volume //successfully. err = PBCatSearchSync(catSearchPB); HUnlock(hBuffer); if (err && (err != eofErr)) break; doneWithVol = (err == eofErr); if ((!err || doneWithVol) && (catSearchPB->ioActMatchCount > 0)) for (ix = 0; ix < catSearchPB->ioActMatchCount; ix++) { if (CheckCancel()) break; //Do something useful with theResults[ix] } } DisposPtr((Ptr)spec1); DisposPtr((Ptr)spec2); DisposPtr((Ptr)catSearchPB); DisposHandle(hBuffer); return true; }
zben@ni.umd.edu (Ben Cranston) (06/28/91)
I'm hacking up MacTCP's dnr.c routine to handle all four permutations of System 6/7 and MacTCP 1.0.2/1.1b1 and got this code to work for finding the MacTCP file in the Control Panels folder in order to find the dnrp resource. BTW System 6.0.7 vs MacTCP 1.1b1 seems to destroy the system file fairly reliably on a Mac SE I'm using for testing. Throw away the GetCPanelFolder subroutine and substitute these two routines for the existing OpenOurRF routine: /* FindFile is used to search Sys7 folder for file with specific signature */ short FindFile(FSSpec *myFSS, OSType mytype, OSType mycreator) { CSParam find; CInfoPBRec spec1, spec2; short err; find.ioNamePtr = nil; find.ioVRefNum = myFSS->vRefNum; find.ioMatchPtr = myFSS; find.ioReqMatchCount = 1; find.ioSearchBits = fsSBFlAttrib + fsSBFlFndrInfo + fsSBFlParID; find.ioSearchInfo1 = &spec1; find.ioSearchInfo2 = &spec2; find.ioSearchTime = 0; find.ioCatPosition.initialize = 0; find.ioOptBuffer = nil; find.ioOptBufSize = 0; spec1.hFileInfo.ioFlAttrib = 0; spec2.hFileInfo.ioFlAttrib = 0x10; spec1.hFileInfo.ioFlFndrInfo.fdType = mytype; spec1.hFileInfo.ioFlFndrInfo.fdCreator = mycreator; spec2.hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF; spec2.hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF; spec2.hFileInfo.ioFlFndrInfo.fdFlags = 0x0000; spec2.hFileInfo.ioFlFndrInfo.fdLocation.h = 0x0000; spec2.hFileInfo.ioFlFndrInfo.fdLocation.v = 0x0000; spec2.hFileInfo.ioFlFndrInfo.fdFldr = 0x0000; spec1.hFileInfo.ioFlParID = myFSS->parID; spec2.hFileInfo.ioFlParID = myFSS->parID; /* ???? */ err = PBCatSearch(&find,false); if (0 < find.ioActMatchCount) return(0); return(fnfErr); } /* OpenOurRF is called to open the MacTCP driver resources */ short OpenOurRF() { Boolean isFolder, wasAlias; SysEnvRec info; Boolean hasFolderMgr; long feature; FSSpec myFSS; ParamBlockRec fi; hasFolderMgr = ( TrapAvailable(_GestaltDispatch) && (noErr==Gestalt(gestaltFindFolderAttr,&feature)) ); if (hasFolderMgr) { if ( FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, &myFSS.vRefNum, &myFSS.parID ) != noErr) return(-1); if (noErr != FindFile(&myFSS,'cdev','ztcp')) if (noErr != FindFile(&myFSS,'cdev','mtcp')) return(-1); if (noErr != ResolveAliasFile(&myFSS,true,&isFolder,&wasAlias)) return(-1); return( FSpOpenResFile(&myFSS, fsRdPerm) ); } else { SysEnvirons(1, &info); fi.fileParam.ioVRefNum = info.sysVRefNum; fi.fileParam.ioNamePtr = &myFSS.name; fi.fileParam.ioFDirIndex = 1; while (noErr == PBGetFInfo(&fi,false) ) { /* scan sys folder for files of MacTCP type & creator */ if (fi.fileParam.ioFlFndrInfo.fdType == 'cdev' && (fi.fileParam.ioFlFndrInfo.fdCreator == 'ztcp' || fi.fileParam.ioFlFndrInfo.fdCreator == 'mtcp') ) /* found the MacTCP driver file */ return( OpenRFPerm(&myFSS.name,info.sysVRefNum, fsRdPerm) ); /* check next file in system folder */ fi.fileParam.ioFDirIndex++; } } return(-1); } I wasn't quite sure what to put into spec2.hFileInfo.ioFlParID for a parent-ID search. IM VI was silent on if this is a high-low range, a mask or it is just ignored. Anybody from Apple want to comment on this???? DE KA3ZDF K