| Jack Jansen | 924ca85 | 1996-09-20 15:25:16 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | ** FindApplicationFromCreator uses the Desktop Database to | 
|  | 3 | ** locate the creator application for the given document | 
|  | 4 | ** | 
|  | 5 | ** this routine will check the desktop database of all local | 
|  | 6 | ** disks, then the desktop databases of all server volumes | 
|  | 7 | ** (so up to two passes will be made) | 
|  | 8 | ** | 
|  | 9 | ** This code was created from FindApplicationFromDocument | 
|  | 10 | ** routine, origin unknown. | 
|  | 11 | */ | 
|  | 12 |  | 
|  | 13 | #include <Types.h> | 
|  | 14 | #include <Files.h> | 
|  | 15 | #include <Errors.h> | 
|  | 16 | #include "getapplbycreator.h" | 
|  | 17 |  | 
|  | 18 |  | 
|  | 19 | OSErr FindApplicationFromCreator(OSType creator, | 
|  | 20 | FSSpecPtr applicationFSSpecPtr) | 
|  | 21 | { | 
|  | 22 | enum { localPass, remotePass, donePass } volumePass; | 
|  | 23 | DTPBRec desktopParams; | 
|  | 24 | HParamBlockRec hfsParams; | 
|  | 25 | short volumeIndex; | 
|  | 26 | Boolean foundFlag; | 
|  | 27 | GetVolParmsInfoBuffer volumeInfoBuffer; | 
|  | 28 | OSErr retCode; | 
|  | 29 |  | 
|  | 30 | /* dkj 12/94 initialize flag to false (thanks to Peter Baral for pointing out this bug) */ | 
|  | 31 | foundFlag = false; | 
|  | 32 |  | 
|  | 33 | volumePass = localPass; | 
|  | 34 | volumeIndex = 0; | 
|  | 35 |  | 
|  | 36 | do { | 
|  | 37 | /* | 
|  | 38 | ** first, find the vRefNum of the volume whose Desktop Database | 
|  | 39 | ** we're checking this time | 
|  | 40 | */ | 
|  | 41 |  | 
|  | 42 | volumeIndex++; | 
|  | 43 |  | 
|  | 44 | /*	convert the volumeIndex into a vRefNum */ | 
|  | 45 |  | 
|  | 46 | hfsParams.volumeParam.ioNamePtr = nil; | 
|  | 47 | hfsParams.volumeParam.ioVRefNum = 0; | 
|  | 48 | hfsParams.volumeParam.ioVolIndex = volumeIndex; | 
|  | 49 | retCode = PBHGetVInfoSync(&hfsParams); | 
|  | 50 |  | 
|  | 51 | /* a nsvErr indicates that the current pass is over */ | 
|  | 52 | if (retCode == nsvErr) goto SkipThisVolume; | 
|  | 53 | if (retCode != noErr) goto Bail; | 
|  | 54 |  | 
|  | 55 | /* | 
|  | 56 | ** call GetVolParms to determine if this volume is a server | 
|  | 57 | ** (a remote volume) | 
|  | 58 | */ | 
|  | 59 |  | 
|  | 60 | hfsParams.ioParam.ioBuffer = (Ptr) &volumeInfoBuffer; | 
|  | 61 | hfsParams.ioParam.ioReqCount = sizeof(GetVolParmsInfoBuffer); | 
|  | 62 | retCode = PBHGetVolParmsSync(&hfsParams); | 
|  | 63 | if (retCode != noErr) goto Bail; | 
|  | 64 |  | 
|  | 65 | /* | 
|  | 66 | ** if the vMServerAdr field of the volume information buffer | 
|  | 67 | ** is zero, this is a local volume; skip this volume | 
|  | 68 | ** if it's local on a remote pass or remote on a local pass | 
|  | 69 | */ | 
|  | 70 |  | 
|  | 71 | if ((volumeInfoBuffer.vMServerAdr != 0) != | 
|  | 72 | (volumePass == remotePass)) goto SkipThisVolume; | 
|  | 73 |  | 
|  | 74 | /* okay, now we've found the vRefNum for our desktop database call */ | 
|  | 75 |  | 
|  | 76 | desktopParams.ioVRefNum = hfsParams.volumeParam.ioVRefNum; | 
|  | 77 |  | 
|  | 78 | /* | 
|  | 79 | ** find the path refNum for the desktop database for | 
|  | 80 | ** the volume we're interested in | 
|  | 81 | */ | 
|  | 82 |  | 
|  | 83 | desktopParams.ioNamePtr = nil; | 
|  | 84 |  | 
|  | 85 | retCode = PBDTGetPath(&desktopParams); | 
|  | 86 | if (retCode == noErr && desktopParams.ioDTRefNum != 0) { | 
|  | 87 |  | 
|  | 88 | /* | 
|  | 89 | ** use the GetAPPL call to find the preferred application | 
|  | 90 | ** for opening any document with this one's creator | 
|  | 91 | */ | 
|  | 92 |  | 
|  | 93 | desktopParams.ioIndex = 0; | 
|  | 94 | desktopParams.ioFileCreator = creator; | 
|  | 95 | desktopParams.ioNamePtr = applicationFSSpecPtr->name; | 
|  | 96 | retCode = PBDTGetAPPLSync(&desktopParams); | 
|  | 97 |  | 
|  | 98 | if (retCode == noErr) { | 
|  | 99 | /* | 
|  | 100 | ** okay, found it; fill in the application file spec | 
|  | 101 | ** and set the flag indicating we're done | 
|  | 102 | */ | 
|  | 103 |  | 
|  | 104 | applicationFSSpecPtr->parID = desktopParams.ioAPPLParID; | 
|  | 105 | applicationFSSpecPtr->vRefNum = desktopParams.ioVRefNum; | 
|  | 106 | foundFlag = true; | 
|  | 107 |  | 
|  | 108 | } | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | SkipThisVolume: | 
|  | 112 | /* | 
|  | 113 | ** if retCode indicates a no such volume error or if this | 
|  | 114 | ** was the first pass, it's time to move on to the next pass | 
|  | 115 | */ | 
|  | 116 |  | 
|  | 117 | if (retCode == nsvErr) { | 
|  | 118 | volumePass++; | 
|  | 119 | volumeIndex = 0; | 
|  | 120 | } | 
|  | 121 |  | 
|  | 122 | } while (foundFlag == false && volumePass != donePass); | 
|  | 123 |  | 
|  | 124 | Bail: | 
|  | 125 | if (retCode == nsvErr) | 
|  | 126 | return fnfErr;		/* More logical than "No such volume" */ | 
|  | 127 | return retCode; | 
|  | 128 | } |