jtn@ADS.COM (John T. Nelson) (03/04/91)
Grak! I'm having problems with PBGetCat and PBGetFInfo. I suspect the problem is because I am not positioned in the correct directory but it's difficult to tell where the problem is. I have a subroutine called directoryP() which tries to test for a directory in the current working directory which I previously set using SetVol() in my function GoToDirectory(). Here's the problem. A call to PBGetFInfo ALWAYS returns -43 which is fnfErr in Mac error results lore. The folder/file I test for is located by SFPGetFile although it is in the same directory that the program is run from. I also have an identical folder located at the root-most directory (because I suspected my working directory wasn't really where I thought it was) and yet it still fails. I set my directories by getting the (long) directory ID of the directory in which to search and then using PBopenWD to get a refNum I can then use with SetVol. Now the funny thing here is that I'm emulating the code that is used in the Unshar utility recently distributed on the net. This utility passes a (long) into SetVol which I think is wrong. SetVol takes an int... not a long. The long dirID passed into GoToDirectory() is derived from the global CurDirSave after doing an SFPGetFile. Here's the code fragment that does that: if (reply.good) { dirVRefNum = reply.vRefNum; if (useCurDir) { dirDirID = CurDirStore; } else { dirDirID = (long)(reply.fType); } } return(dirDirID); GoToDirectory(long dirID) { long dID; /* short dID; */ /* int dID */ wdpb.ioCompletion = NIL; wdpb.ioNamePtr = NIL; wdpb.ioVRefNum = dirVRefNum; wdpb.ioWDDirID = dirID; if (PBOpenWD(&wdpb, FALSE) != noErr) { return; } dID = dirVRefNum = wdpb.ioVRefNum; (void)SetVol(NIL, dID); } Boolean directoryP(Str255 file) { Str255 vName; int vRefNum; CInfoPBRec cBlock; OSErr err; cBlock.dirInfo.ioCompletion = NIL; cBlock.dirInfo.ioNamePtr = file; GetVol(&vName, &vRefNum); /*cBlock.dirInfo.ioVRefNum = - ( *(short *) SFSaveDisk );*/ cBlock.dirInfo.ioVRefNum = vRefNum; cBlock.dirInfo.ioFDirIndex = 0; err = PBGetFInfo(&cBlock, SYNCHRONOUS); if ( err == fnfErr ) return FALSE; if ( cBlock.dirInfo.ioFlAttrib & 0x010 ) return TRUE; else return FALSE; } Any ideas on what I'm doing wrong? =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ORGANIZATION: Advanced Decision Systems GEOGRAPHIC: Arlington, VA UUCP: kzin!speaker@mimsy.umd.edu INTERNET: jtn@potomac.ads.com SPOKEN: Dark Hacker PHONE: (703) 243-1611 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
tim@hoptoad.uucp (Tim Maroney) (03/09/91)
In article <$$B&70=@ads.com> jtn@ADS.COM (John T. Nelson) writes: > >Grak! I'm having problems with PBGetCat and PBGetFInfo. > > if (reply.good) { > dirVRefNum = reply.vRefNum; > if (useCurDir) > dirDirID = CurDirStore; > else dirDirID = (long)(reply.fType); > } > return(dirDirID); First off, I don't know how you could *ever* trust reply.fType to have a dir ID *after* Standard File returns. Sure it has one during your filter procedure, but afterwards? Completely undocumented. Even if you put one there yoruself, Standard File may put something else in. But let's assume that useCurDir is always true. >GoToDirectory(long dirID) >{ >long dID; > > wdpb.ioCompletion = NIL; > wdpb.ioNamePtr = NIL; > wdpb.ioVRefNum = dirVRefNum; > wdpb.ioWDDirID = dirID; > if (PBOpenWD(&wdpb, FALSE) != noErr) { > return; > } > > dID = dirVRefNum = wdpb.ioVRefNum; > (void)SetVol(NIL, dID); >} Here, in all probability, is your problem. You are using SF's vRefNum as a volume reference number, when in fact it's a working directory reference number. Then you try to make a new working directory out of the old WD refnum and a dir ID. Guaranteed to give some kind of silly result. If you want to SetVol to the place SF picked, then just use the reply.vRefNum, and cut out all this CurDirStore and PBOpenWD stuff! >Boolean directoryP(Str255 file) { >Str255 vName; >int vRefNum; >CInfoPBRec cBlock; >OSErr err; > >cBlock.dirInfo.ioCompletion = NIL; >cBlock.dirInfo.ioNamePtr = file; > >GetVol(&vName, &vRefNum); > >/*cBlock.dirInfo.ioVRefNum = - ( *(short *) SFSaveDisk );*/ >cBlock.dirInfo.ioVRefNum = vRefNum; >cBlock.dirInfo.ioFDirIndex = 0; > >err = PBGetFInfo(&cBlock, SYNCHRONOUS); >if ( err == fnfErr ) > return FALSE; > >if ( cBlock.dirInfo.ioFlAttrib & 0x010 ) > return TRUE; >else > return FALSE; >} PBGetFInfo doesn't work on folders. You have to use PBGetCatInfo. Here's what I would do -- take the vRefNum from Standard File. Don't even bother doing a SetVol. Use PBGetWDInfo to turn the reply.vRefNum into a volume reference number and a working directory reference number. Then put these into a PBGetCatInfo parameter block and do your thing. Here's a little Pascal routine that illustrates the PBGetWDInfo step. Read the PBGetCatinfo documentation carefully; and volume IV explains the relationship of these three kinds of numbers reasonably well, so I recommend brushing up on it first, cause otherwise, it's really easy to get lost. procedure WDtoPair(wdRefNum: integer; var volume: integer; var folder: longint); { find the volume/refnum pair for a working directory } var wd: WDPBRec; begin wd.ioVRefNum := wdRefNum; wd.ioNamePtr := nil; wd.ioWDIndex := 0; FailOSErr(PBGetWDInfo(@wd, false)); volume := wd.ioWDVRefNum; folder := wd.ioWDDirID; end; -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com This message does represent the views of Eclectic Software.