mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
	
	
		
			129 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			129 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  | ** FindApplicationFromCreator uses the Desktop Database to | ||
|  | ** locate the creator application for the given document | ||
|  | ** | ||
|  | ** this routine will check the desktop database of all local | ||
|  | ** disks, then the desktop databases of all server volumes | ||
|  | ** (so up to two passes will be made) | ||
|  | ** | ||
|  | ** This code was created from FindApplicationFromDocument | ||
|  | ** routine, origin unknown. | ||
|  | */ | ||
|  | 
 | ||
|  | #include <Types.h>
 | ||
|  | #include <Files.h>
 | ||
|  | #include <Errors.h>
 | ||
|  | #include "getapplbycreator.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | OSErr FindApplicationFromCreator(OSType creator, | ||
|  |         FSSpecPtr applicationFSSpecPtr) | ||
|  | { | ||
|  |         enum { localPass, remotePass, donePass } volumePass; | ||
|  |         DTPBRec desktopParams; | ||
|  |         HParamBlockRec hfsParams; | ||
|  |         short volumeIndex; | ||
|  |         Boolean foundFlag; | ||
|  |         GetVolParmsInfoBuffer volumeInfoBuffer; | ||
|  |         OSErr retCode; | ||
|  | 
 | ||
|  | /* dkj 12/94 initialize flag to false (thanks to Peter Baral for pointing out this bug) */ | ||
|  |         foundFlag = false; | ||
|  | 
 | ||
|  |         volumePass = localPass; | ||
|  |         volumeIndex = 0; | ||
|  | 
 | ||
|  |         do { | ||
|  | 				/*
 | ||
|  |                 ** first, find the vRefNum of the volume whose Desktop Database | ||
|  |                 ** we're checking this time | ||
|  | 				*/ | ||
|  | 
 | ||
|  | 				volumeIndex++; | ||
|  | 
 | ||
|  | 				/*	convert the volumeIndex into a vRefNum */ | ||
|  | 
 | ||
|  | 				hfsParams.volumeParam.ioNamePtr = nil; | ||
|  | 				hfsParams.volumeParam.ioVRefNum = 0; | ||
|  | 				hfsParams.volumeParam.ioVolIndex = volumeIndex; | ||
|  | 				retCode = PBHGetVInfoSync(&hfsParams); | ||
|  | 
 | ||
|  | 				/* a nsvErr indicates that the current pass is over */ | ||
|  | 				if (retCode == nsvErr) goto SkipThisVolume; | ||
|  | 				if (retCode != noErr) goto Bail; | ||
|  | 
 | ||
|  | 				/*
 | ||
|  | 				** call GetVolParms to determine if this volume is a server | ||
|  | 				** (a remote volume) | ||
|  | 				*/ | ||
|  | 				 | ||
|  | 				hfsParams.ioParam.ioBuffer = (Ptr) &volumeInfoBuffer; | ||
|  | 				hfsParams.ioParam.ioReqCount = sizeof(GetVolParmsInfoBuffer); | ||
|  | 				retCode = PBHGetVolParmsSync(&hfsParams); | ||
|  | 				if (retCode != noErr) goto Bail; | ||
|  | 				 | ||
|  | 				/*
 | ||
|  | 				** if the vMServerAdr field of the volume information buffer | ||
|  | 				** is zero, this is a local volume; skip this volume | ||
|  | 				** if it's local on a remote pass or remote on a local pass | ||
|  | 				*/ | ||
|  | 				 | ||
|  | 				if ((volumeInfoBuffer.vMServerAdr != 0) != | ||
|  | 						(volumePass == remotePass)) goto SkipThisVolume; | ||
|  | 
 | ||
|  | 				/* okay, now we've found the vRefNum for our desktop database call */ | ||
|  | 
 | ||
|  | 				desktopParams.ioVRefNum = hfsParams.volumeParam.ioVRefNum; | ||
|  | 
 | ||
|  | 				/*
 | ||
|  |                 ** find the path refNum for the desktop database for | ||
|  |                 ** the volume we're interested in | ||
|  |                 */ | ||
|  | 
 | ||
|  |                 desktopParams.ioNamePtr = nil; | ||
|  | 
 | ||
|  |                 retCode = PBDTGetPath(&desktopParams); | ||
|  |                 if (retCode == noErr && desktopParams.ioDTRefNum != 0) { | ||
|  | 
 | ||
|  | 						/*
 | ||
|  |                         ** use the GetAPPL call to find the preferred application | ||
|  |                         ** for opening any document with this one's creator | ||
|  |                         */ | ||
|  | 
 | ||
|  |                         desktopParams.ioIndex = 0; | ||
|  |                         desktopParams.ioFileCreator = creator; | ||
|  |                         desktopParams.ioNamePtr = applicationFSSpecPtr->name; | ||
|  |                         retCode = PBDTGetAPPLSync(&desktopParams); | ||
|  | 
 | ||
|  |                         if (retCode == noErr) { | ||
|  | 								/*
 | ||
|  |                                 ** okay, found it; fill in the application file spec | ||
|  |                                 ** and set the flag indicating we're done | ||
|  |                                 */ | ||
|  | 
 | ||
|  |                                 applicationFSSpecPtr->parID = desktopParams.ioAPPLParID; | ||
|  |                                 applicationFSSpecPtr->vRefNum = desktopParams.ioVRefNum; | ||
|  |                                 foundFlag = true; | ||
|  | 
 | ||
|  |                         } | ||
|  |                 } | ||
|  | 
 | ||
|  |         SkipThisVolume: | ||
|  | 				/*
 | ||
|  |                 ** if retCode indicates a no such volume error or if this | ||
|  |                 ** was the first pass, it's time to move on to the next pass | ||
|  |                 */ | ||
|  | 
 | ||
|  |                 if (retCode == nsvErr) { | ||
|  |                         volumePass++; | ||
|  |                         volumeIndex = 0; | ||
|  |                 } | ||
|  | 
 | ||
|  |         } while (foundFlag == false && volumePass != donePass); | ||
|  | 
 | ||
|  | Bail: | ||
|  | 		if (retCode == nsvErr) | ||
|  | 			return fnfErr;		/* More logical than "No such volume" */ | ||
|  |         return retCode; | ||
|  | } |