pascal OSErr FSpResolveFileIDRef(ConstStr255Param volName, short vRefNum, long fileID, FSSpec *spec) { OSErr error; error = DetermineVRefNum(volName, vRefNum, &(spec->vRefNum)); if ( error == noErr ) { error = ResolveFileIDRef(volName, vRefNum, fileID, &(spec->parID), spec->name); } return ( error ); }
static OSErr MacPathname2FSSpec(const char *inPathname, FSSpec *outFSS) { OSErr err; size_t len; char *p; short vRefNum; long dirID; FSSpec fss; if (inPathname == NULL || outFSS == NULL) { return paramErr; } err = HGetVol(NULL, &vRefNum, &dirID); /* default volume and directory */ if (err != noErr) return err; len = strlen(inPathname); p = strchr(inPathname, ':'); if (p == NULL) { /* Partial pathname -- filename only */ Str31 filename; assert(len <= 31); c2pstrcpy(filename, inPathname); err = FSMakeFSSpec(vRefNum, dirID, filename, outFSS); } else { Str31 name; int nameLen; if (inPathname[0] == ':') { /* Relative pathname including directory path */ } else { /* Absolute pathname */ /* Str31 volName; We would use Str28 if it was defined -- 27, plus 1 for ':'. */ nameLen = p - inPathname; assert(nameLen <= 27); name[0] = nameLen + 1; memcpy(name + 1, inPathname, nameLen + 1); /* Copy the volume name and the colon. */ err = DetermineVRefNum(name, 0, &vRefNum); if (err != noErr) return err; dirID = 2; } /* vRefNum and dirID now specify the directory in which we should descend the path pointed to by p (pointing to the first colon). */ p++; while (p != NULL && *p != '\0') { char *q = strchr(p, ':'); if (q != NULL) { Boolean isDir; nameLen = q - p; assert(nameLen <= 31); name[0] = nameLen; memcpy(name + 1, p, nameLen); err = FSMakeFSSpec(vRefNum, dirID, name, &fss); if (err != noErr) return err; if (q[1] == '\0') { p = NULL; *outFSS = fss; } else { err = FSpGetDirectoryID(&fss, &dirID, &isDir); assert(isDir == true); if (err != noErr) return err; p = q + 1; } } else { q = strchr(p, '\0'); /* go to end of string */ nameLen = q - p; assert(nameLen > 0); assert(nameLen <= 31); c2pstrcpy(name, p); p = NULL; err = FSMakeFSSpec(vRefNum, dirID, name, outFSS); } } } return err; }
/* ** GetIconFromDesktopFile ** ** INPUT a pointer to a non-existent Handle, because we'll allocate one ** ** search each BNDL resource for the right fileCreator and once we get it ** find the 'FREF' type in BNDL ** for each localID in the type, open the FREF resource ** if the FREF is the desired fileType ** get its icon localID ** get the ICN# type in BNDL ** get the icon resource number from the icon localID ** get the icon resource type from the desktop mgr's iconType ** get the icon of that type and number */ static OSErr GetIconFromDesktopFile(ConstStr255Param volName, short vRefNum, short iconType, OSType fileCreator, OSType fileType, Handle *iconHandle) { OSErr error; short realVRefNum; Str255 desktopName; short savedResFile; short dfRefNum; BNDLRecHandle theBndl = NULL; BundleTypePtr theBundleType; short iconLocalID; short iconRsrcID; OSType iconRsrcType; Handle returnIconHandle; char bndlState; *iconHandle = NULL; error = DetermineVRefNum(volName, vRefNum, &realVRefNum); if ( error == noErr ) { error = GetDesktopFileName(realVRefNum, desktopName); if ( error == noErr ) { savedResFile = CurResFile(); /* ** Open the 'Desktop' file in the root directory. (because ** opening the resource file could preload unwanted resources, ** bracket the call with SetResLoad(s)) */ SetResLoad(false); dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, fsRdPerm); SetResLoad(true); if ( dfRefNum != -1 ) { /* ** Find the BNDL resource with the specified creator. */ error = FindBundleGivenCreator(fileCreator, &theBndl); if ( error == noErr ) { /* Lock the BNDL resource so it won't be purged when other resources are loaded */ bndlState = HGetState((Handle)theBndl); HLock((Handle)theBndl); /* Find the 'FREF' BundleType record in the BNDL resource. */ error = FindTypeInBundle(kFREFResType, theBndl, &theBundleType); if ( error == noErr ) { /* Find the local ID in the 'FREF' resource with the specified fileType */ error = GetLocalIDFromFREF(theBundleType, fileType, &iconLocalID); if ( error == noErr ) { /* Find the 'ICN#' BundleType record in the BNDL resource. */ error = FindTypeInBundle(kIconFamResType, theBndl, &theBundleType); if ( error == noErr ) { /* Find the icon's resource ID in the 'ICN#' BundleType record */ error = GetIconRsrcIDFromLocalID(theBundleType, iconLocalID, &iconRsrcID); if ( error == noErr ) { /* Map Desktop Manager icon type to resource type */ iconRsrcType = DTIconToResIcon(iconType); if ( iconRsrcType != (OSType)0 ) { /* Load the icon */ returnIconHandle = Get1Resource(iconRsrcType, iconRsrcID); if ( returnIconHandle != NULL ) { /* Copy the resource handle, and return the copy */ HandToHand(&returnIconHandle); if ( MemError() == noErr ) { *iconHandle = returnIconHandle; } else { error = afpItemNotFound; } } else { error = afpItemNotFound; } } } } } } /* Restore the state of the BNDL resource */ HSetState((Handle)theBndl, bndlState); } /* Restore the resource chain and close the Desktop file */ UseResFile(savedResFile); CloseResFile(dfRefNum); } else { error = ResError(); /* could not open Desktop file */ } } if ( (error != noErr) && (error != memFullErr) ) { error = afpItemNotFound; /* force an error we should return */ } } return ( error ); }
pascal OSErr DTXGetAPPL(ConstStr255Param volName, short vRefNum, OSType creator, Boolean searchCatalog, short *applVRefNum, long *applParID, Str255 applName) { OSErr error; UniversalFMPB pb; short dtRefNum; Boolean newDTDatabase; short realVRefNum; short index; Boolean applFound; FSSpec spec; long actMatchCount; /* get the real vRefNum */ error = DetermineVRefNum(volName, vRefNum, &realVRefNum); if ( error == noErr ) { error = DTOpen(volName, vRefNum, &dtRefNum, &newDTDatabase); if ( error == noErr ) { if ( !newDTDatabase ) { index = 0; applFound = false; do { pb.dtPB.ioNamePtr = applName; pb.dtPB.ioDTRefNum = dtRefNum; pb.dtPB.ioIndex = index; pb.dtPB.ioFileCreator = creator; error = PBDTGetAPPLSync(&pb.dtPB); if ( error == noErr ) { /* got a match - see if it is valid */ *applVRefNum = realVRefNum; /* get the vRefNum now */ *applParID = pb.dtPB.ioAPPLParID; /* get the parent ID now */ /* pb.hPB.fileParam.ioNamePtr is already set */ pb.hPB.fileParam.ioVRefNum = realVRefNum; pb.hPB.fileParam.ioFVersNum = 0; pb.hPB.fileParam.ioDirID = *applParID; pb.hPB.fileParam.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ if ( PBHGetFInfoSync(&pb.hPB) == noErr ) { if ( (pb.hPB.fileParam.ioFlFndrInfo.fdCreator == creator) && (pb.hPB.fileParam.ioFlFndrInfo.fdType == 'APPL') ) { applFound = true; } } } ++index; } while ( (error == noErr) && !applFound ); if ( error != noErr ) { error = afpItemNotFound; } } else { /* Desktop database is empty (new), set error to try CatSearch */ error = afpItemNotFound; } } /* acceptable errors from Desktop Manager to continue are paramErr or afpItemNotFound */ if ( error == paramErr ) { /* if paramErr, the volume didn't support the Desktop Manager */ /* try the Desktop file */ error = GetAPPLFromDesktopFile(volName, vRefNum, creator, applVRefNum, applParID, applName); if ( error == noErr ) { /* got a match - see if it is valid */ pb.hPB.fileParam.ioNamePtr = applName; pb.hPB.fileParam.ioVRefNum = *applVRefNum; pb.hPB.fileParam.ioFVersNum = 0; pb.hPB.fileParam.ioDirID = *applParID; pb.hPB.fileParam.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ if ( PBHGetFInfoSync(&pb.hPB) == noErr ) { if ( (pb.hPB.fileParam.ioFlFndrInfo.fdCreator != creator) || (pb.hPB.fileParam.ioFlFndrInfo.fdType != 'APPL') ) { error = afpItemNotFound; } } else if ( error == fnfErr ) { error = afpItemNotFound; } } } /* acceptable error from DesktopFile code to continue is afpItemNotFound */ if ( (error == afpItemNotFound) && searchCatalog) { /* Couldn't be found in the Desktop file either, */ /* try searching with CatSearch if requested */ error = CreatorTypeFileSearch(NULL, realVRefNum, creator, kAPPLResType, &spec, 1, &actMatchCount, true); if ( (error == noErr) || (error == eofErr) ) { if ( actMatchCount > 0 ) { *applVRefNum = spec.vRefNum; *applParID = spec.parID; BlockMoveData(spec.name, applName, spec.name[0] + 1); } else { error = afpItemNotFound; } } } } return ( error ); }
/* ** GetAPPLFromDesktopFile ** ** Get a application's location from the ** Desktop file's 'APPL' resources. */ static OSErr GetAPPLFromDesktopFile(ConstStr255Param volName, short vRefNum, OSType creator, short *applVRefNum, long *applParID, Str255 applName) { OSErr error; short realVRefNum; Str255 desktopName; short savedResFile; short dfRefNum; Handle applResHandle; Boolean foundCreator; Ptr applPtr; long applSize; error = DetermineVRefNum(volName, vRefNum, &realVRefNum); if ( error == noErr ) { error = GetDesktopFileName(realVRefNum, desktopName); if ( error == noErr ) { savedResFile = CurResFile(); /* ** Open the 'Desktop' file in the root directory. (because ** opening the resource file could preload unwanted resources, ** bracket the call with SetResLoad(s)) */ SetResLoad(false); dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, fsRdPerm); SetResLoad(true); if ( dfRefNum != -1) { /* Get 'APPL' resource ID 0 */ applResHandle = Get1Resource(kAPPLResType, 0); if ( applResHandle != NULL ) { applSize = GetHandleSize((Handle)applResHandle); if ( applSize != 0 ) /* make sure the APPL resource isn't empty */ { foundCreator = false; applPtr = *applResHandle; /* APPL's don't have a count so I have to use the size as the bounds */ while ( (foundCreator == false) && (applPtr < (*applResHandle + applSize)) ) { if ( ((APPLRecPtr)applPtr)->creator == creator ) { foundCreator = true; } else { /* fun with pointer math... */ applPtr += sizeof(OSType) + sizeof(long) + ((APPLRecPtr)applPtr)->applName[0] + 1; /* application mappings are word aligned within the resource */ if ( ((unsigned long)applPtr % 2) != 0 ) { applPtr += 1; } } } if ( foundCreator == true ) { *applVRefNum = realVRefNum; *applParID = ((APPLRecPtr)applPtr)->parID; BlockMoveData(((APPLRecPtr)applPtr)->applName, applName, ((APPLRecPtr)applPtr)->applName[0] + 1); /* error is already noErr */ } else { error = afpItemNotFound; /* didn't find a creator match */ } } else { error = afpItemNotFound; /* no APPL mapping available */ } } else { error = afpItemNotFound; /* no APPL mapping available */ } /* restore the resource chain and close the Desktop file */ UseResFile(savedResFile); CloseResFile(dfRefNum); } else { error = afpItemNotFound; } } } return ( error ); }
/* ** GetCommentFromDesktopFile ** ** Get a file or directory's Finder comment field (if any) from the ** Desktop file's 'FCMT' resources. */ static OSErr GetCommentFromDesktopFile(short vRefNum, long dirID, ConstStr255Param name, Str255 comment) { OSErr error; short commentID; short realVRefNum; Str255 desktopName; short savedResFile; short dfRefNum; StringHandle commentHandle; /* Get the comment ID number */ error = GetCommentID(vRefNum, dirID, name, &commentID); if ( error == noErr ) { if ( commentID != 0 ) /* commentID == 0 means there's no comment */ { error = DetermineVRefNum(name, vRefNum, &realVRefNum); if ( error == noErr ) { error = GetDesktopFileName(realVRefNum, desktopName); if ( error == noErr ) { savedResFile = CurResFile(); /* ** Open the 'Desktop' file in the root directory. (because ** opening the resource file could preload unwanted resources, ** bracket the call with SetResLoad(s)) */ SetResLoad(false); dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, fsRdPerm); SetResLoad(true); if ( dfRefNum != -1) { /* Get the comment resource */ commentHandle = (StringHandle)Get1Resource(kFCMTResType,commentID); if ( commentHandle != NULL ) { if ( GetHandleSize((Handle)commentHandle) > 0 ) { BlockMoveData(*commentHandle, comment, *commentHandle[0] + 1); } else { error = afpItemNotFound; /* no comment available */ } } else { error = afpItemNotFound; /* no comment available */ } /* restore the resource chain and close the Desktop file */ UseResFile(savedResFile); CloseResFile(dfRefNum); } else { error = afpItemNotFound; } } else { error = afpItemNotFound; } } } else { error = afpItemNotFound; /* no comment available */ } } return ( error ); }
pascal OSErr CreatorTypeFileSearch(ConstStr255Param volName, short vRefNum, OSType creator, OSType fileType, FSSpecPtr matches, long reqMatchCount, long *actMatchCount, Boolean newSearch) { CInfoPBRec searchInfo1, searchInfo2; HParamBlockRec pb; OSErr error; static CatPositionRec catPosition; static short lastVRefNum = 0; /* get the real volume reference number */ error = DetermineVRefNum(volName, vRefNum, &vRefNum); if ( error != noErr ) return ( error ); pb.csParam.ioNamePtr = NULL; pb.csParam.ioVRefNum = vRefNum; pb.csParam.ioMatchPtr = matches; pb.csParam.ioReqMatchCount = reqMatchCount; pb.csParam.ioSearchBits = fsSBFlAttrib + fsSBFlFndrInfo; /* Looking for finder info file matches */ pb.csParam.ioSearchInfo1 = &searchInfo1; pb.csParam.ioSearchInfo2 = &searchInfo2; pb.csParam.ioSearchTime = 0; if ( (newSearch) || /* If caller specified new search */ (lastVRefNum != vRefNum) ) /* or if last search was to another volume, */ { catPosition.initialize = 0; /* then search from beginning of catalog */ } pb.csParam.ioCatPosition = catPosition; pb.csParam.ioOptBuffer = GetTempBuffer(0x00004000, &pb.csParam.ioOptBufSize); /* no fileName */ searchInfo1.hFileInfo.ioNamePtr = NULL; searchInfo2.hFileInfo.ioNamePtr = NULL; /* only match files (not directories) */ searchInfo1.hFileInfo.ioFlAttrib = 0x00; searchInfo2.hFileInfo.ioFlAttrib = kioFlAttribDirMask; /* search for creator; if creator = 0x00000000, ignore creator */ searchInfo1.hFileInfo.ioFlFndrInfo.fdCreator = creator; if ( creator == (OSType)0x00000000 ) { searchInfo2.hFileInfo.ioFlFndrInfo.fdCreator = (OSType)0x00000000; } else { searchInfo2.hFileInfo.ioFlFndrInfo.fdCreator = (OSType)0xffffffff; } /* search for fileType; if fileType = 0x00000000, ignore fileType */ searchInfo1.hFileInfo.ioFlFndrInfo.fdType = fileType; if ( fileType == (OSType)0x00000000 ) { searchInfo2.hFileInfo.ioFlFndrInfo.fdType = (OSType)0x00000000; } else { searchInfo2.hFileInfo.ioFlFndrInfo.fdType = (OSType)0xffffffff; } /* zero all other FInfo fields */ searchInfo1.hFileInfo.ioFlFndrInfo.fdFlags = 0; searchInfo1.hFileInfo.ioFlFndrInfo.fdLocation.v = 0; searchInfo1.hFileInfo.ioFlFndrInfo.fdLocation.h = 0; searchInfo1.hFileInfo.ioFlFndrInfo.fdFldr = 0; searchInfo2.hFileInfo.ioFlFndrInfo.fdFlags = 0; searchInfo2.hFileInfo.ioFlFndrInfo.fdLocation.v = 0; searchInfo2.hFileInfo.ioFlFndrInfo.fdLocation.h = 0; searchInfo2.hFileInfo.ioFlFndrInfo.fdFldr = 0; error = PBCatSearchSyncCompat((CSParamPtr)&pb); if ( (error == noErr) || /* If no errors or the end of catalog was */ (error == eofErr) ) /* found, then the call was successful so */ { *actMatchCount = pb.csParam.ioActMatchCount; /* return the match count */ } else { *actMatchCount = 0; /* else no matches found */ } if ( (error == noErr) || /* If no errors */ (error == catChangedErr) ) /* or there was a change in the catalog */ { catPosition = pb.csParam.ioCatPosition; lastVRefNum = vRefNum; /* we can probably start the next search where we stopped this time */ } else { catPosition.initialize = 0; /* start the next search from beginning of catalog */ } if ( pb.csParam.ioOptBuffer != NULL ) { DisposePtr(pb.csParam.ioOptBuffer); } return ( error ); }
pascal OSErr NameFileSearch(ConstStr255Param volName, short vRefNum, ConstStr255Param fileName, FSSpecPtr matches, long reqMatchCount, long *actMatchCount, Boolean newSearch, Boolean partial) { CInfoPBRec searchInfo1, searchInfo2; HParamBlockRec pb; OSErr error; static CatPositionRec catPosition; static short lastVRefNum = 0; /* get the real volume reference number */ error = DetermineVRefNum(volName, vRefNum, &vRefNum); if ( error != noErr ) return ( error ); pb.csParam.ioNamePtr = NULL; pb.csParam.ioVRefNum = vRefNum; pb.csParam.ioMatchPtr = matches; pb.csParam.ioReqMatchCount = reqMatchCount; if ( partial ) /* tell CatSearch what we're looking for: */ { pb.csParam.ioSearchBits = fsSBPartialName + fsSBFlAttrib; /* partial name file matches or */ } else { pb.csParam.ioSearchBits = fsSBFullName + fsSBFlAttrib; /* full name file matches */ } pb.csParam.ioSearchInfo1 = &searchInfo1; pb.csParam.ioSearchInfo2 = &searchInfo2; pb.csParam.ioSearchTime = 0; if ( (newSearch) || /* If caller specified new search */ (lastVRefNum != vRefNum) ) /* or if last search was to another volume, */ { catPosition.initialize = 0; /* then search from beginning of catalog */ } pb.csParam.ioCatPosition = catPosition; pb.csParam.ioOptBuffer = GetTempBuffer(0x00004000, &pb.csParam.ioOptBufSize); /* search for fileName */ searchInfo1.hFileInfo.ioNamePtr = (StringPtr)fileName; searchInfo2.hFileInfo.ioNamePtr = NULL; /* only match files (not directories) */ searchInfo1.hFileInfo.ioFlAttrib = 0x00; searchInfo2.hFileInfo.ioFlAttrib = kioFlAttribDirMask; error = PBCatSearchSyncCompat((CSParamPtr)&pb); if ( (error == noErr) || /* If no errors or the end of catalog was */ (error == eofErr) ) /* found, then the call was successful so */ { *actMatchCount = pb.csParam.ioActMatchCount; /* return the match count */ } else { *actMatchCount = 0; /* else no matches found */ } if ( (error == noErr) || /* If no errors */ (error == catChangedErr) ) /* or there was a change in the catalog */ { catPosition = pb.csParam.ioCatPosition; lastVRefNum = vRefNum; /* we can probably start the next search where we stopped this time */ } else { catPosition.initialize = 0; /* start the next search from beginning of catalog */ } if ( pb.csParam.ioOptBuffer != NULL ) { DisposePtr(pb.csParam.ioOptBuffer); } return ( error ); }