summaryrefslogtreecommitdiffstats
path: root/Mac
diff options
context:
space:
mode:
Diffstat (limited to 'Mac')
-rw-r--r--Mac/Include/getapplbycreator.h4
-rw-r--r--Mac/Modules/macfsmodule.c21
-rw-r--r--Mac/Python/getapplbycreator.c128
3 files changed, 153 insertions, 0 deletions
diff --git a/Mac/Include/getapplbycreator.h b/Mac/Include/getapplbycreator.h
new file mode 100644
index 0000000..4ff60fa
--- /dev/null
+++ b/Mac/Include/getapplbycreator.h
@@ -0,0 +1,4 @@
+#include <Types.h>
+#include <Files.h>
+
+extern OSErr FindApplicationFromCreator(OSType, FSSpecPtr);
diff --git a/Mac/Modules/macfsmodule.c b/Mac/Modules/macfsmodule.c
index 831fd65..91e63eb 100644
--- a/Mac/Modules/macfsmodule.c
+++ b/Mac/Modules/macfsmodule.c
@@ -34,6 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <LowMem.h>
#include "nfullpath.h"
+#include "getapplbycreator.h"
#ifdef THINK_C
#define FileFilterUPP FileFilterProcPtr
@@ -895,6 +896,25 @@ mfs_FindFolder(self, args)
}
static object *
+mfs_FindApplication(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ OSErr err;
+ OSType which;
+ FSSpec fss;
+
+ if (!newgetargs(args, "O&", PyMac_GetOSType, &which) )
+ return NULL;
+ err = FindApplicationFromCreator(which, &fss);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return (object *)newmfssobject(&fss);
+}
+
+static object *
mfs_FInfo(self, args)
object *self;
object *args;
@@ -915,6 +935,7 @@ static struct methodlist mfs_methods[] = {
{"RawFSSpec", mfs_RawFSSpec, 1},
{"RawAlias", mfs_RawAlias, 1},
{"FindFolder", mfs_FindFolder, 1},
+ {"FindApplication", mfs_FindApplication, 1},
{"FInfo", mfs_FInfo, 1},
{NULL, NULL} /* sentinel */
diff --git a/Mac/Python/getapplbycreator.c b/Mac/Python/getapplbycreator.c
new file mode 100644
index 0000000..3370f31
--- /dev/null
+++ b/Mac/Python/getapplbycreator.c
@@ -0,0 +1,128 @@
+/*
+** 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;
+}