Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!batcomputer!munnari.oz.au!spool.mu.edu!mips!zaphod.mps.ohio-state.edu!usc!apple!casseres@apple.com From: casseres@apple.com (David Casseres) Newsgroups: comp.sys.mac.programmer Subject: Re: out to do PBCatSearch based on type/creator Message-ID: <14194@goofy.Apple.COM> Date: 21 Jun 91 23:29:45 GMT References: <1991Jun18.032741.24056@cec1.wustl.edu> Sender: usenet@Apple.COM Distribution: usa Organization: Apple Computer Lines: 101 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; }