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 );
}
示例#2
0
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;
}
示例#3
0
/*
**	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 );
}
示例#4
0
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 );
}
示例#5
0
/*
**	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 );
}
示例#6
0
/*
**	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 );
}
示例#7
0
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 );
}
示例#8
0
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 );
}