blob: 3370f31da0521a885161a66154dcb0454a0deb01 [file] [log] [blame]
Jack Jansen924ca851996-09-20 15:25:16 +00001/*
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
19OSErr 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
124Bail:
125 if (retCode == nsvErr)
126 return fnfErr; /* More logical than "No such volume" */
127 return retCode;
128}